
Перем МетаданныеОписание Экспорт;
Перем СсылочныеТипы Экспорт;
Перем СоответствиеОбъектовМетаданныхИСсылочныхТипов;
Перем ОбработанныхКонстант Экспорт;
Перем ОбработанныхНаборовЗаписей Экспорт;
Перем мСоответствиеКолонокДвижений;

// массив строк дерева метаданных, имеющих признак Выгружать
Перем СоставПолнойВыгрузки Экспорт;
// массив строк дерева метаданных, имеющих признак выгрузки по ссылке
Перем СоставВспомогательнойВыгрузки;

// массив регистров, использующих итоги
Перем ИспользующиеИтоги;

Перем мТипРезультатЗапроса;
Перем мТипДанныхУдаления;

Перем мВыгруженныеОбъекты;
//Перем мКоличествоСохраненныхПоследнихВыгрузок;

Перем мНаличиеВыгрузкиПодчиненныхОбъектов;
Перем ТаблицаПредопределенных;
Перем СоответствиеЗаменыСсылок;
Перем Сериализатор;
Функция СведенияОВнешнейОбработке() Экспорт
	// Объявим переменную, в которой мы сохраним и вернем "наружу" необходимые данные
	ПараметрыРегистрации = Новый Структура;
	// Первый параметр, который мы должны указать - это какой вид обработки системе должна зарегистрировать. 
	// Допустимые типы: ДополнительнаяОбработка, ДополнительныйОтчет, ЗаполнениеОбъекта, Отчет, ПечатнаяФорма, СозданиеСвязанныхОбъектов

	ПараметрыРегистрации.Вставить("Вид", "ДополнительнаяОбработка");
	// Теперь зададим имя, под которым ВПФ будет зарегистрирована в справочнике внешних обработок
	ПараметрыРегистрации.Вставить("Наименование", "Выгрузка - загрузка данных XML 8.3");
	// Зададим право обработке на использование безопасного режима. Более подробно можно узнать в справке к платформе (метод УстановитьБезопасныйРежим)
	ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
	// Следующие два параметра играют больше информационную роль, т.е. это то, что будет видеть пользователь в информации к обработке
	ПараметрыРегистрации.Вставить("Версия", "1.0");
	ПараметрыРегистрации.Вставить("Информация", "Выгрузка - загрузка данных XML 8.3");
	// Создадим таблицу команд (подробнее смотрим ниже)

	ТаблицаКоманд = ПолучитьТаблицуКоманд();
	// Добавим команду в таблицу

	ДобавитьКоманду(ТаблицаКоманд, ЭтотОбъект.Метаданные().Представление(),    // Представление команды в пользовательском интерфейсе

		Метаданные().ПолноеИмя(), // Уникальный идентификатор команды

		"ОткрытиеФормы", Истина, );
	ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
	// Теперь вернем системе наши параметры

	Возврат ПараметрыРегистрации
	//
КонецФункции

//2) Вспомогательные функции***********************************************************
Функция ПолучитьТаблицуКоманд()

   // Создадим пустую таблицу команд и колонки в ней
	Команды = Новый ТаблицаЗначений;

   // Как будет выглядеть описание печатной формы для пользователя
	Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка")); 

   // Имя нашего макета, что бы могли отличить вызванную команду в обработке печати
	Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));

   // Тут задается, как должна вызваться команда обработки
   // Возможные варианты:
   // - ОткрытиеФормы - в этом случае в колонке идентификатор должно быть указано имя формы, которое должна будет открыть система
   // - ВызовКлиентскогоМетода - вызвать клиентскую экспортную процедуру из модуля формы обработки
   // - ВызовСерверногоМетода - вызвать серверную экспортную процедуру из модуля объекта обработки
	Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));

   // Следующий параметр указывает, необходимо ли показывать оповещение при начале и завершению работы обработки. Не имеет смысла при открытии формы
	Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));

   // Для печатной формы должен содержать строку ПечатьMXL 
	Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
	Возврат Команды;
КонецФункции

Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь,
	Модификатор = "")
  // Добавляем команду в таблицу команд по переданному описанию.
  // Параметры и их значения можно посмотреть в функции ПолучитьТаблицуКоманд
	НоваяКоманда = ТаблицаКоманд.Добавить();
	НоваяКоманда.Представление = Представление;
	НоваяКоманда.Идентификатор = Идентификатор;
	НоваяКоманда.Использование = Использование;
	НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
	НоваяКоманда.Модификатор = Модификатор;

КонецПроцедуры


// Процедура создает файл выгрузки
//
// Параметры
//   ИмяФайла - имя файла выгрузки
//
Процедура ВыполнитьВыгрузку(Знач ИмяФайла, ТолькоПроверкаНедопустимыхСимволов = Ложь, ТаблицаОтбора1) Экспорт

	ОбъектыВыгруженныеСОшибками = Новый Соответствие;

	СоставВыгрузки();

	Если СоставПолнойВыгрузки.Количество() = 0 И ДополнительныеОбъектыДляВыгрузки.Количество() = 0 Тогда

		СообщитьПользователю(Нстр("ru = 'Не задан состав выгрузки'"));
		Возврат;

	КонецЕсли;

	Если ТолькоПроверкаНедопустимыхСимволов Тогда

		ЗаписьXML = СоздатьОбъектЗаписиXMLДляПроверки();

		ВыгрузкаДанных(ЗаписьXML, ТолькоПроверкаНедопустимыхСимволов, ОбъектыВыгруженныеСОшибками, ТаблицаОтбора1);

	Иначе

		Если ИспользоватьФорматFastInfoSet Тогда

			ЗаписьXML = Новый ЗаписьFastInfoset;
			ЗаписьXML.ОткрытьФайл(ИмяФайла);

		Иначе

			ЗаписьXML = Новый ЗаписьXML;
			ЗаписьXML.ОткрытьФайл(ИмяФайла, "UTF-8");

		КонецЕсли;

		ЗаписьXML.ЗаписатьОбъявлениеXML();
		ЗаписьXML.ЗаписатьНачалоЭлемента("_1CV8DtUD", "http://www.1c.ru/V8/1CV8DtUD/");
		ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("V8Exch", "http://www.1c.ru/V8/1CV8DtUD/");
		ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance");
		ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("core", "http://v8.1c.ru/data");

		ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("v8", "http://v8.1c.ru/8.1/data/enterprise/current-config");
		ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xs", "http://www.w3.org/2001/XMLSchema");

		ЗаписьXML.ЗаписатьНачалоЭлемента("V8Exch:Data");

		Если ТолькоПроверкаНедопустимыхСимволов Тогда

			ШаблонНачалоПроверки = Нстр("ru = 'Начало проверки: %Дата'");
			СообщениеНачалоПроверки = СтрЗаменить(ШаблонНачалоПроверки, "%Дата", ТекущаяДатаСеанса());
			СообщитьПользователю(СообщениеНачалоПроверки);

		Иначе

			ШаблонНачалоВыгрузки = Нстр("ru = 'Начало выгрузки: %Дата'");
			СообщениеНачалоВыгрузки = СтрЗаменить(ШаблонНачалоВыгрузки, "%Дата", ТекущаяДатаСеанса());
			СообщитьПользователю(СообщениеНачалоВыгрузки);

		КонецЕсли;

		ИнициализироватьСериализаторXDTOСАннотациейТипов();

		ВыгрузкаДанных(ЗаписьXML, , , ТаблицаОтбора1);

		ЗаписьXML.ЗаписатьКонецЭлемента(); //V8Exc:Data
		ВыгрузитьТаблицуПредопределенных(ЗаписьXML);
		ЗаписьXML.ЗаписатьКонецЭлемента(); //V8Exc:_1CV8DtUD

	КонецЕсли;

	Если ТолькоПроверкаНедопустимыхСимволов Тогда

		ШаблонПроверено = Нстр("ru = 'Проверено объектов: %Проверено'");
		СообщениеПроверено = СтрЗаменить(ШаблонПроверено, "%Проверено", ВсегоОбработанныхЗаписей());
		СообщитьПользователю(СообщениеПроверено);

		ШаблонОкончание = Нстр("ru = 'Окончание проверки: %Дата'");
		СообщениеОкончание = СтрЗаменить(ШаблонОкончание, "%Дата", ТекущаяДатаСеанса());
		СообщитьПользователю(СообщениеОкончание);

	Иначе

		ШаблонВыгружено = Нстр("ru = 'Выгружено объектов: %Выгружено'");
		СообщениеВыгружено = СтрЗаменить(ШаблонВыгружено, "%Выгружено", ВсегоОбработанныхЗаписей());
		СообщитьПользователю(СообщениеВыгружено);

		ШаблонОкончание = Нстр("ru = 'Окончание выгрузки: %Дата'");
		СообщениеОкончание = СтрЗаменить(ШаблонОкончание, "%Дата", ТекущаяДатаСеанса());
		СообщитьПользователю(СообщениеОкончание);

		СообщитьПользователю(Нстр("ru = 'Выгрузка данных успешно завершена'"));

	КонецЕсли;

КонецПроцедуры

// Процедура разбирает файл выгрузки и осуществляет запись в ИБ сохраненных
// там объектов
//
// Параметры
//   ИмяФайла - имя файла выгрузки
//
Процедура ВыполнитьЗагрузку(Знач ИмяФайла) Экспорт

	Файл = Новый Файл(ИмяФайла);

	Если Файл.Расширение = ".fi" Тогда

		ЧтениеXML = Новый ЧтениеFastInfoset;
		ЧтениеXML.Прочитать();
		ЧтениеXML.ОткрытьФайл(ИмяФайла);

		ЗаписьXML = Новый ЗаписьXML;
		ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xml");
		ЗаписьXML.ОткрытьФайл(ИмяВременногоФайла, "UTF-8");

		Пока ЧтениеXML.Прочитать() Цикл

			ЗаписьXML.ЗаписатьТекущий(ЧтениеXML);

		КонецЦикла;

		ЗаписьXML.Закрыть();

		ИмяФайла = ИмяВременногоФайла;

	КонецЕсли;

	ЧтениеXML = Новый ЧтениеXML;
	ЧтениеXML.ОткрытьФайл(ИмяФайла);
	// проверка формата файла обмена
	Если Не ЧтениеXML.Прочитать() Или ЧтениеXML.ТипУзла <> ТипУзлаXML.НачалоЭлемента Или ЧтениеXML.ЛокальноеИмя <> "_1CV8DtUD"
		Или ЧтениеXML.URIПространстваИмен <> "http://www.1c.ru/V8/1CV8DtUD/" Тогда

		СообщитьПользователю(Нстр("ru = 'Неверный формат файла выгрузки'"));
		Возврат;

	КонецЕсли;

	Если Не ЧтениеXML.Прочитать() Или ЧтениеXML.ТипУзла <> ТипУзлаXML.НачалоЭлемента Или ЧтениеXML.ЛокальноеИмя
		<> "Data" Тогда

		СообщитьПользователю(Нстр("ru = 'Неверный формат файла выгрузки'"));
		Возврат;

	КонецЕсли;

	Если Не ЭтотОбъект.РежимЗагрузкиПредопределенных = 2 Тогда
		ЗагрузитьТаблицуПредопределенных(ЧтениеXML);
		ЗаменитьСсылкиНаПредопределенные(ИмяФайла);
	КонецЕсли;

	ЧтениеXML.ОткрытьФайл(ИмяФайла);
	ЧтениеXML.Прочитать();
	ЧтениеXML.Прочитать();
	
	// чтение и запись в ИБ записанных в выгрузке объектов
	Если Не ЧтениеXML.Прочитать() Тогда

		СообщитьПользователю(Нстр("ru = 'Неверный формат файла выгрузки'"));
		Возврат;

	КонецЕсли;

	Загружено = 0;
	УбратьИспользованиеИтогов();

	ШаблонСообщения = Нстр("ru = 'Начало загрузки: %Дата'");
	ТекстСообщения = СтрЗаменить(ШаблонСообщения, "%Дата", ТекущаяДатаСеанса());

	СообщитьПользователю(ТекстСообщения);

	ИнициализироватьСериализаторXDTOСАннотациейТипов();

	Пока Сериализатор.ВозможностьЧтенияXML(ЧтениеXML) Цикл

		Попытка
			ЗаписанноеЗначение = Сериализатор.ПрочитатьXML(ЧтениеXML);
		Исключение
			ВосстановитьИспользованиеИтогов();
			ВызватьИсключение;
		КонецПопытки;

		Если ПриЗагрузкеИспользоватьРежимОбменаДанными Тогда

			Попытка // Планы обмена свойства ОбменДанными не имеют
				ЗаписанноеЗначение.ОбменДанными.Загрузка = Истина;
			Исключение
			КонецПопытки;

		КонецЕсли;

		Попытка
			ЗаписанноеЗначение.Записать();
		Исключение

			ТекстОшибки = ОписаниеОшибки();

			Если Не ПродолжитьЗагрузкуВСлучаеВозникновенияОшибки Тогда

				ВосстановитьИспользованиеИтогов();
				ВызватьИсключение;

			Иначе

				Попытка
					ТекстСообщения = Нстр("ru = 'При загрузке объекта %1(%2) возникла ошибка:
										  |%3'");
					ТекстСообщения = ПодставитьПараметрыВСтроку(ТекстСообщения, ЗаписанноеЗначение, ТипЗнч(
						ЗаписанноеЗначение), ТекстОшибки);
				Исключение
					ТекстСообщения = Нстр("ru = 'При загрузке данных возникла ошибка:
										  |%1'");
					ТекстСообщения = ПодставитьПараметрыВСтроку(ТекстСообщения, ТекстОшибки);
				КонецПопытки;

				СообщитьПользователю(ТекстСообщения);

			КонецЕсли;

			Загружено = Загружено - 1;

		КонецПопытки;

		Загружено = Загружено + 1;

	КонецЦикла;

	ВосстановитьИспользованиеИтогов();
	
	// проверка формата файла обмена
	Если ЧтениеXML.ТипУзла <> ТипУзлаXML.КонецЭлемента Или ЧтениеXML.ЛокальноеИмя <> "Data" Тогда

		СообщитьПользователю(Нстр("ru = 'Неверный формат файла выгрузки'"));
		Возврат;

	КонецЕсли;

	Если Не ЧтениеXML.Прочитать() Или ЧтениеXML.ТипУзла <> ТипУзлаXML.НачалоЭлемента Или ЧтениеXML.ЛокальноеИмя
		<> "PredefinedData" Тогда

		СообщитьПользователю(Нстр("ru = 'Неверный формат файла выгрузки'"));
		Возврат;

	КонецЕсли;

	ЧтениеXML.Пропустить();

	Если Не ЧтениеXML.Прочитать() Или ЧтениеXML.ТипУзла <> ТипУзлаXML.КонецЭлемента Или ЧтениеXML.ЛокальноеИмя <> "_1CV8DtUD"
		Или ЧтениеXML.URIПространстваИмен <> "http://www.1c.ru/V8/1CV8DtUD/" Тогда

		СообщитьПользователю(Нстр("ru = 'Неверный формат файла выгрузки'"));
		Возврат;

	КонецЕсли;

	ЧтениеXML.Закрыть();

	ШаблонЗагружено = Нстр("ru = 'Загружено объектов: %Количество'");
	СообщениеЗагружено = СтрЗаменить(ШаблонЗагружено, "%Количество", Загружено);

	ШаблонОкончание = Нстр("ru = 'Окончание загрузки: %Дата'");
	СообщениеОкончание = СтрЗаменить(ШаблонОкончание, "%Дата", ТекущаяДатаСеанса());

	СообщитьПользователю(СообщениеЗагружено);
	СообщитьПользователю(СообщениеОкончание);
	СообщитьПользователю(Нстр("ru = 'Загрузка данных успешно завершена'"));

КонецПроцедуры

//

// Процедура производит начальную инициализацию - заполнение дерева описания
// классов объектов метаданных, дерево метаданных, список ссылочных типов
//
// Параметры
//
Процедура Инициализация() Экспорт

	ВключитьВозможностьРедактированияИспользованияИтогов = Ложь;
	
	// Создаем объект, описывающий процессы построения дерева и выгрузку
	ЗаполнитьОписаниеМетаданных();

	МетаданныеОписание = МетаданныеОписание.Строки[0];

	СсылочныеТипы = Новый Соответствие;
	СоответствиеОбъектовМетаданныхИСсылочныхТипов = Новый Соответствие;

	ДеревоМетаданных.Колонки.Очистить();
	// создание необходимых колонок
	ДеревоМетаданных.Колонки.Добавить("Выгружать", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(1, 0,
		ДопустимыйЗнак.Неотрицательный)));
	ДеревоМетаданных.Колонки.Добавить("ВыгружатьПриНеобходимости", Новый ОписаниеТипов("Число",
		Новый КвалификаторыЧисла(1, 0, ДопустимыйЗнак.Неотрицательный)));
	ДеревоМетаданных.Колонки.Добавить("Метаданные");
	ДеревоМетаданных.Колонки.Добавить("ЭлементОписания");
	ДеревоМетаданных.Колонки.Добавить("ИмяОбъектаМетаданных");
	ДеревоМетаданных.Колонки.Добавить("ОбъектМД");
	ДеревоМетаданных.Колонки.Добавить("ПолноеИмяМетаданных");
	ДеревоМетаданных.Колонки.Добавить("НастройкиПостроителя");
	ДеревоМетаданных.Колонки.Добавить("ИспользоватьОтбор");
	ДеревоМетаданных.Колонки.Добавить("ИндексКартинки");
	//ДеревоМетаданных.Колонки.Добавить("ИндексВДереве");

	ДеревоМетаданных.Колонки.Добавить("Развернут");

	ИспользующиеИтоги = Новый Массив;
	Корень = ДеревоМетаданных.Строки.Добавить();
	ПостроениеПоддереваОбъекта(Метаданные, Корень, МетаданныеОписание);
	СверткаПоддереваОбъекта(Корень);

	Для Каждого Эл Из СсылочныеТипы Цикл
		СоответствиеОбъектовМетаданныхИСсылочныхТипов.Вставить(Эл.Значение, Эл.Ключ);
	КонецЦикла;

КонецПроцедуры

Функция СоздатьОбъектЗаписиXMLДляПроверки()

	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.УстановитьСтроку("UTF-16");
	ЗаписьXML.ЗаписатьНачалоЭлемента("Проверка");

	Возврат ЗаписьXML;

КонецФункции

// Для внутреннего использования
//
Процедура ВыполнитьПроверкуДляВыгрузкиОбъектовИзПланаОбмена(СсылкаНаУзел) Экспорт

	ОбъектыВыгруженныеСОшибками = Новый Соответствие;
	ВсегоОбработаноОбъектов = 0;
	КоличествоОшибок = 0;

	ЗаписьXML = СоздатьОбъектЗаписиXMLДляПроверки();

	СоставВыгрузки();
	МассивМетаданныхДляВыгрузки = Новый Массив;

	Для Каждого СтрокаТаблицыВыгрузки Из СоставПолнойВыгрузки Цикл

		СтрокаДереваМетаданных = СтрокаТаблицыВыгрузки.СтрокаДерева;

		МассивМетаданныхДляВыгрузки.Добавить(СтрокаДереваМетаданных.ОбъектМД);

	КонецЦикла;

	Если МассивМетаданныхДляВыгрузки.Количество() = 0 Тогда
		МассивМетаданныхДляВыгрузки = Неопределено;
	КонецЕсли;

	ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(СсылкаНаУзел, СсылкаНаУзел.НомерОтправленного + 1,
		МассивМетаданныхДляВыгрузки);
	Пока ВыборкаИзменений.Следующий() Цикл
		
		// измененный элемент
		Данные = ВыборкаИзменений.Получить();
		
		// данные должны быть
		Если Данные = Неопределено Тогда
			Продолжить;
		КонецЕсли;

		ЭтоУдаление = (мТипДанныхУдаления = ТипЗнч(Данные));

		Если ЭтоУдаление Тогда
			Продолжить;
		КонецЕсли;

		ВсегоОбработаноОбъектов = ВсегоОбработаноОбъектов + 1;

		МетаданныеОбъекта = Данные.Метаданные();

		Попытка

			ВыполнитьВспомогательныеДействияДляЗаписиXML(ВсегоОбработаноОбъектов, ЗаписьXML, Истина);

			Сериализатор.ЗаписатьXML(ЗаписьXML, Данные);

		Исключение

			КоличествоОшибок = КоличествоОшибок + 1;

			СтрокаОписанияОшибки = ОписаниеОшибки();
			
			// для ссылочных добавляем ссылку, а для не ссылочных сам объект
			ЭтоНеСсылка = Метаданные.РегистрыСведений.Содержит(МетаданныеОбъекта)
				Или Метаданные.РегистрыНакопления.Содержит(МетаданныеОбъекта)
				Или Метаданные.РегистрыБухгалтерии.Содержит(МетаданныеОбъекта) Или Метаданные.Константы.Содержит(
				МетаданныеОбъекта);

			Если ЭтоНеСсылка Тогда

				ОбъектыВыгруженныеСОшибками.Вставить(Данные, СтрокаОписанияОшибки);

			Иначе

				Если ОбъектыВыгруженныеСОшибками.Получить(Данные.Ссылка) = Неопределено Тогда
					ОбъектыВыгруженныеСОшибками.Вставить(Данные.Ссылка, СтрокаОписанияОшибки);
				КонецЕсли;

			КонецЕсли;

		КонецПопытки;

	КонецЦикла;

	СформироватьТаблицуОшибок(ОбъектыВыгруженныеСОшибками);

КонецПроцедуры

Процедура СформироватьТаблицуОшибок(ОбъектыВыгруженныеСОшибками)

	Если ОбъектыВыгруженныеСОшибками.Количество() = 0 Тогда
		СообщитьПользователю(Нстр(
			"ru = 'Проверка объектов на наличие недопустимых символов завершена. Ошибок не обнаружено.'"));
	Иначе

		СтрокаПоискаОшибки = "ЗаписатьXML):";
		ДлинаСтрокиПоиска = СтрДлина(СтрокаПоискаОшибки);

		ТаблицаДанных = Новый ТаблицаЗначений;
		ТаблицаДанных.Колонки.Добавить("Объект");
		ТаблицаДанных.Колонки.Добавить("ТекстОшибки");

		Для Каждого СтрокаСоответствия Из ОбъектыВыгруженныеСОшибками Цикл

			СтрокаТаблицы = ТаблицаДанных.Добавить();
			СтрокаТаблицы.Объект = Строка(СтрокаСоответствия.Ключ);
			
			// служебные символы удалим из ошибки
			ТекстСообщения = СформироватьТекстСообщенияБезСлужебныхСимволов(СтрокаСоответствия.Значение);

			ПозицияНачалаОшибки = Найти(ТекстСообщения, "ЗаписатьXML):");
			Если ПозицияНачалаОшибки > 0 Тогда

				ТекстСообщения = Сред(ТекстСообщения, ПозицияНачалаОшибки + ДлинаСтрокиПоиска);

			КонецЕсли;

			СтрокаТаблицы.ТекстОшибки = СокрЛП(ТекстСообщения);

		КонецЦикла;

	КонецЕсли;

КонецПроцедуры

Функция СформироватьТекстСообщенияБезСлужебныхСимволов(Знач ТекстСообщения)

	НачалоСлужебногоСообщения    = Найти(ТекстСообщения, "{");
	ОкончаниеСлужебногоСообщения = Найти(ТекстСообщения, "}:");

	Если ОкончаниеСлужебногоСообщения > 0 И НачалоСлужебногоСообщения > 0 И НачалоСлужебногоСообщения
		< ОкончаниеСлужебногоСообщения Тогда

		ТекстСообщения = Лев(ТекстСообщения, (НачалоСлужебногоСообщения - 1)) + Сред(ТекстСообщения,
			(ОкончаниеСлужебногоСообщения + 2));

	КонецЕсли;

	Возврат СокрЛП(ТекстСообщения);

КонецФункции // ()

// Процедура рекурсивно обрабатывает дерево метаданных, образуя списки полной и вспомогательной выгрузки
//
// Параметры
//
Процедура СоставВыгрузки(ПересчитатьВыгружаемыеПоСсылке = Ложь) Экспорт

	СоставПолнойВыгрузки = Новый ТаблицаЗначений;
	СоставПолнойВыгрузки.Колонки.Добавить("ОбъектМД");
	СоставПолнойВыгрузки.Колонки.Добавить("СтрокаДерева");
	СоставПолнойВыгрузки.Индексы.Добавить("ОбъектМД");

	СоставВспомогательнойВыгрузки = Новый ТаблицаЗначений;
	СоставВспомогательнойВыгрузки.Колонки.Добавить("ОбъектМД");
	СоставВспомогательнойВыгрузки.Колонки.Добавить("СтрокаДерева");
	СоставВспомогательнойВыгрузки.Индексы.Добавить("ОбъектМД");

	Для Каждого СтрокаДЗ Из ДеревоМетаданных.Строки Цикл
		ДобавитьВыгружаемыеОбъекты(СоставПолнойВыгрузки, СоставВспомогательнойВыгрузки, СтрокаДЗ);
	КонецЦикла;

	мНаличиеВыгрузкиПодчиненныхОбъектов = СоставВспомогательнойВыгрузки.Количество() > 0;

	Если ПересчитатьВыгружаемыеПоСсылке Тогда

		ПересчитатьВыгружаемыеПоСсылке(СоставПолнойВыгрузки);

	КонецЕсли;

КонецПроцедуры

Процедура ВыгрузитьДанныеМассиваСсылок(МассивСсылок, СтрокаИмяДляЗапроса, ЗаписьXML,
	ТолькоПроверкаНедопустимыхСимволов = Ложь, ОбъектыВыгруженныеСОшибками = Неопределено, ТаблицаОтбора1)

	Если МассивСсылок.Количество() = 0 Или Не ЗначениеЗаполнено(СтрокаИмяДляЗапроса) Тогда

		Возврат;

	КонецЕсли;

	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ разрешенные ТаблицаОбъекта_.*
				   |	
				   |ИЗ
				   |	" + СтрокаИмяДляЗапроса + " КАК ТаблицаОбъекта_
												  |ГДЕ
												  |	ТаблицаОбъекта_.Ссылка В(&МассивСсылок)";

	Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);

	РезультатЗапроса = Запрос.Выполнить();

	ЗапросИЗапись(РезультатЗапроса, ЗаписьXML, Истина, ОбъектыВыгруженныеСОшибками, ТолькоПроверкаНедопустимыхСимволов);

КонецПроцедуры

// Процедура записывает наборы записей регистра (накопления, бухгалтерии...)
//
// Параметры
//   ЗаписьXML - объект, через которых происходит запись объектов ИБ
//
Процедура ВыгрузкаДанных(ЗаписьXML, ТолькоПроверкаНедопустимыхСимволов = Ложь,
	ОбъектыВыгруженныеСОшибками = Неопределено, ТаблицаОтбора1)

	мВыгруженныеОбъекты = Новый ТаблицаЗначений;
	мВыгруженныеОбъекты.Колонки.Добавить("Ссылка");
	мВыгруженныеОбъекты.Индексы.Добавить("Ссылка");

	ИнициализироватьТаблицуПредопределенных();

	Если ОбъектыВыгруженныеСОшибками = Неопределено Тогда
		ОбъектыВыгруженныеСОшибками = Новый Соответствие;
	КонецЕсли;

	Попытка

		Для Каждого СтрокаТаблицыВыгрузки Из СоставПолнойВыгрузки Цикл

			СтрокаДереваМетаданных = СтрокаТаблицыВыгрузки.СтрокаДерева;

			Если СтрокаДереваМетаданных.ЭлементОписания.Менеджер = Неопределено Тогда
				ВызватьИсключение (Нстр("ru = 'Выгрузка данных. Внутренняя ошибка'"));
			КонецЕсли;

			Если Метаданные.Константы.Содержит(СтрокаДереваМетаданных.ОбъектМД) Тогда

				ЗаписьКонстанты(ЗаписьXML, СтрокаДереваМетаданных.ОбъектМД, ОбъектыВыгруженныеСОшибками,
					ТолькоПроверкаНедопустимыхСимволов, ТаблицаОтбора1);

			ИначеЕсли Метаданные.РегистрыСведений.Содержит(СтрокаДереваМетаданных.ОбъектМД)
				Или Метаданные.РегистрыНакопления.Содержит(СтрокаДереваМетаданных.ОбъектМД)
				Или Метаданные.РегистрыРасчета.Содержит(СтрокаДереваМетаданных.ОбъектМД) Тогда

				ЗаписьРегистра(ЗаписьXML, СтрокаДереваМетаданных, ОбъектыВыгруженныеСОшибками,
					ТолькоПроверкаНедопустимыхСимволов, , ТаблицаОтбора1);

			ИначеЕсли Метаданные.РегистрыБухгалтерии.Содержит(СтрокаДереваМетаданных.ОбъектМД) Тогда

				ЗаписьРегистра(ЗаписьXML, СтрокаДереваМетаданных, ОбъектыВыгруженныеСОшибками,
					ТолькоПроверкаНедопустимыхСимволов, Истина, ТаблицаОтбора1);

			ИначеЕсли ТипЗнч(СтрокаДереваМетаданных.ЭлементОписания.Менеджер) = Тип("Строка") Тогда
				// специальный случай для перерасчетов
				ЗаписьПерерасчета(ЗаписьXML, СтрокаДереваМетаданных, ОбъектыВыгруженныеСОшибками,
					ТолькоПроверкаНедопустимыхСимволов, ТаблицаОтбора1);

			ИначеЕсли Метаданные.Последовательности.Содержит(СтрокаДереваМетаданных.ОбъектМД) Тогда

				ЗаписьПоследовательности(ЗаписьXML, СтрокаДереваМетаданных, ОбъектыВыгруженныеСОшибками,
					ТолькоПроверкаНедопустимыхСимволов, ТаблицаОтбора1);

			Иначе

				ЗаписьДанныхОбъектногоТипа(СтрокаДереваМетаданных, ЗаписьXML, ОбъектыВыгруженныеСОшибками,
					ТолькоПроверкаНедопустимыхСимволов, ТаблицаОтбора1);

			КонецЕсли;

		КонецЦикла;

		ДополнительныеОбъектыДляВыгрузки.Сортировать("ИмяОбъектаДляЗапроса");
		ТекущийМассивСсылок = Новый Массив;
		ТекущееИмяЗапроса = "";

		Для Каждого СтрокаТаблицыВыгрузки Из ДополнительныеОбъектыДляВыгрузки Цикл

			Если Не ЗначениеЗаполнено(СтрокаТаблицыВыгрузки.Объект) Или Не ЗначениеЗаполнено(
				СтрокаТаблицыВыгрузки.ИмяОбъектаДляЗапроса) Тогда

				Продолжить;

			КонецЕсли;

			Если ТекущееИмяЗапроса <> СтрокаТаблицыВыгрузки.ИмяОбъектаДляЗапроса Тогда

				ВыгрузитьДанныеМассиваСсылок(ТекущийМассивСсылок, ТекущееИмяЗапроса, ЗаписьXML,
					ТолькоПроверкаНедопустимыхСимволов, ОбъектыВыгруженныеСОшибками, ТаблицаОтбора1);

				ТекущийМассивСсылок = Новый массив;
				ТекущееИмяЗапроса = СтрокаТаблицыВыгрузки.ИмяОбъектаДляЗапроса;

			КонецЕсли;

			ТекущийМассивСсылок.Добавить(СтрокаТаблицыВыгрузки.Объект);

		КонецЦикла;

		ВыгрузитьДанныеМассиваСсылок(ТекущийМассивСсылок, ТекущееИмяЗапроса, ЗаписьXML,
			ТолькоПроверкаНедопустимыхСимволов, ОбъектыВыгруженныеСОшибками, ТаблицаОтбора1);

	Исключение
		ВызватьИсключение;
	КонецПопытки;

КонецПроцедуры

// Для внутреннего использования
//
Функция ПолучитьСтрокуОграниченияПоДатеДляЗапроса(Свойства, ИмяТипа) Экспорт

	ИтоговоеОграничениеПоДате = "";
	ИмяАлиасаТаблицы = Свойства.Имя;

	Если Не (ИмяТипа = "Документ" Или ИмяТипа = "РегистрСведений" Или ИмяТипа = "Регистр") Тогда
		Возврат ИтоговоеОграничениеПоДате;
	КонецЕсли;

	ИмяПоляОграничения = ИмяАлиасаТаблицы + "." + ?(ИмяТипа = "Документ", "Дата", "Период");

	Если ЗначениеЗаполнено(ДатаНачала) Тогда

		ИтоговоеОграничениеПоДате = "
									|	ГДЕ
									|		ТаблицаОбъекта_" + ИмяПоляОграничения + " >= &ДатаНачала";

	КонецЕсли;

	Если ЗначениеЗаполнено(ДатаОкончания) Тогда

		Если ПустаяСтрока(ИтоговоеОграничениеПоДате) Тогда

			ИтоговоеОграничениеПоДате = "
										|	ГДЕ
										|		ТаблицаОбъекта_" + ИмяПоляОграничения + " <= &ДатаОкончания";

		Иначе

			ИтоговоеОграничениеПоДате = ИтоговоеОграничениеПоДате + "
																	|	И
																	|		ТаблицаОбъекта_" + ИмяПоляОграничения
				+ " <= &ДатаОкончания";

		КонецЕсли;

	КонецЕсли;

	Возврат ИтоговоеОграничениеПоДате;

КонецФункции


// Для внутреннего использования
//
Функция ПолучитьТекстЗапросаДляРегистраСведений(ИмяМетаданных, ОбъектМетаданных, ЕстьДопОтборы,
	СтрокаПолейДляВыборки = "", СтрокаПолейДляВыборки1 = "", ТаблицаОтбора1)

	ЕстьОграничениеПоДатам = (ЗначениеЗаполнено(ДатаНачала) Или ЗначениеЗаполнено(ДатаОкончания));

	Если Не ЗначениеЗаполнено(СтрокаПолейДляВыборки) Тогда
		СтрокаПолейДляВыборки ="ТаблицаОбъекта_" + ОбъектМетаданных.ИМЯ + ".*";
		СтрокаПолейДляВыборки1="ТаблицаОбъекта_" + ОбъектМетаданных.ИМЯ + "1.*";

	Иначе
		СтрокаПолейДляВыборки1 = " Различные " + СтрокаПолейДляВыборки1;
		СтрокаПолейДляВыборки = " Различные " + СтрокаПолейДляВыборки;
	КонецЕсли;

	ТекстЗапроса = "ВЫБРАТЬ Разрешенные " + СтрокаПолейДляВыборки + " ИЗ " + ИмяМетаданных + " КАК ТаблицаОбъекта_"
		+ ОбъектМетаданных.ИМЯ;
	
	//Если ОбъектМетаданных.ПериодичностьРегистраСведений = Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
	//	Возврат ТекстЗапроса;
	//КонецЕсли;
	
	// 0 - отбор за период
	// 1 - срез последних на дату окончания
	// 2 - срез первых на дату начала
	// 3 - срез последних на дату начала + отбор за период

	Первая=Истина;

	Если ОбъектМетаданных.ПериодичностьРегистраСведений
		= Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда

	ИначеЕсли ТипВыгрузкиПериодическихРегистров = 0 Тогда

		Если ЕстьДопОтборы И Не ИспользоватьОтборПоДатеДляВсехОбъектов Тогда

		Иначе
			Если ЕстьОграничениеПоДатам Тогда
				ДопОграничениеПоДате = ПолучитьСтрокуОграниченияПоДатеДляЗапроса(ОбъектМетаданных, "РегистрСведений");

				ТекстЗапроса = ТекстЗапроса + Символы.ПС + ДопОграничениеПоДате;
				Первая=Ложь;
			КонецЕсли;
		КонецЕсли;
	ИначеЕсли ТипВыгрузкиПериодическихРегистров = 1 Тогда

		ТекстЗапроса = "ВЫБРАТЬ Разрешенные " + СтрокаПолейДляВыборки + " ИЗ " + ИмяМетаданных
			+ ".СрезПоследних(&ДатаОкончания) КАК ТаблицаОбъекта_" + ОбъектМетаданных.ИМЯ;

	ИначеЕсли ТипВыгрузкиПериодическихРегистров = 2 Тогда

		ТекстЗапроса = "ВЫБРАТЬ Разрешенные " + СтрокаПолейДляВыборки + " ИЗ " + ИмяМетаданных
			+ ".СрезПервых(&ДатаНачала) КАК ТаблицаОбъекта_" + ОбъектМетаданных.ИМЯ;

	ИначеЕсли ТипВыгрузкиПериодическихРегистров = 3 Тогда

		ТекстЗапроса = "ВЫБРАТЬ Разрешенные " + СтрокаПолейДляВыборки1 + " ИЗ " + ИмяМетаданных
			+ ".СрезПоследних(&ДатаНачала) КАК ТаблицаОбъекта_" + ОбъектМетаданных.ИМЯ + "1
																						 |
																						 |Объединить все
																						 |
																						 |ВЫБРАТЬ "
			+ СтрокаПолейДляВыборки + " ИЗ " + ИмяМетаданных + " КАК ТаблицаОбъекта_" + ОбъектМетаданных.ИМЯ + "
																											   |";

		ДопОграничениеПоДате = ПолучитьСтрокуОграниченияПоДатеДляЗапроса(ОбъектМетаданных, "РегистрСведений");

		ТекстЗапроса = ТекстЗапроса + Символы.ПС + ДопОграничениеПоДате;

		Первая=Ложь;

	КонецЕсли;

	Для Каждого Строка Из ТаблицаОтбора1 Цикл
		Если ОбъектМетаданных.ИМЯ = Строка.имяреквизита Тогда
			Для Каждого СтрокаЭлементы Из Строка.Отбор.Элементы Цикл
				Если СтрокаЭлементы.Использование Тогда

					Если Не Первая Тогда
						ТекстЗапроса = ТекстЗапроса + Символы.ПС + " И " + ПолучитьВидСравненияВЗапрос(Строка,
							СтрокаЭлементы, СтрокаЭлементы.ВидСравнения);
					Иначе
						ТекстЗапроса = ТекстЗапроса + Символы.ПС + " ГДЕ " + ПолучитьВидСравненияВЗапрос(Строка,
							СтрокаЭлементы, СтрокаЭлементы.ВидСравнения);
					КонецЕсли;
					Первая=Ложь;
				КонецЕсли;
			КонецЦикла;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	Возврат ТекстЗапроса;

КонецФункции

Функция ПолучитьТекстЗапросаДляРегистра(ИмяМетаданных, ОбъектМетаданных, ЕстьДопОтборы, СтрокаПолейДляВыборки = "",
	ТаблицаОтбора1)

	ЕстьОграничениеПоДатам = (ЗначениеЗаполнено(ДатаНачала) Или ЗначениеЗаполнено(ДатаОкончания))
		И ИспользоватьОтборПоДатеДляВсехОбъектов;

	Если Не ЗначениеЗаполнено(СтрокаПолейДляВыборки) Тогда
		СтрокаПолейДляВыборки = "ТаблицаОбъекта_" + ОбъектМетаданных.ИМЯ + ".*";
	Иначе
		//СтрокаПолейДляВыборки = " РАЗЛИЧНЫЕ ТаблицаОбъекта_" + ОбъектМетаданных.ИМЯ+"."+ СтрокаПолейДляВыборки;
		
	КонецЕсли;

	ТекстЗапроса = "ВЫБРАТЬ Разрешенные " + СтрокаПолейДляВыборки + " ИЗ " + ИмяМетаданных + " КАК ТаблицаОбъекта_"
		+ ОбъектМетаданных.ИМЯ;

	Первая=Истина;
	// возможно нужно ограничение по датам установить
	Если ЕстьОграничениеПоДатам Тогда

		Если ЕстьДопОтборы И Не ИспользоватьОтборПоДатеДляВсехОбъектов Тогда

			Возврат ТекстЗапроса;

		КонецЕсли;

		ДопОграничениеПоДате = ПолучитьСтрокуОграниченияПоДатеДляЗапроса(ОбъектМетаданных, "Регистр");

		ТекстЗапроса = ТекстЗапроса + Символы.ПС + ДопОграничениеПоДате;

		Первая=Ложь;
	КонецЕсли;
	Для Каждого Строка Из ТаблицаОтбора1 Цикл
		Если ОбъектМетаданных.ИМЯ = Строка.имяреквизита Тогда
			Для Каждого СтрокаЭлементы Из Строка.Отбор.Элементы Цикл
				Если СтрокаЭлементы.Использование Тогда

					Если Не Первая Тогда
						ТекстЗапроса = ТекстЗапроса + Символы.ПС + " И " + ПолучитьВидСравненияВЗапрос(Строка,
							СтрокаЭлементы, СтрокаЭлементы.ВидСравнения);
					Иначе
						ТекстЗапроса = ТекстЗапроса + Символы.ПС + " ГДЕ " + ПолучитьВидСравненияВЗапрос(Строка,
							СтрокаЭлементы, СтрокаЭлементы.ВидСравнения);
					КонецЕсли;
					Первая=Ложь;
				КонецЕсли;
			КонецЦикла;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	Возврат ТекстЗапроса;

КонецФункции

// Для внутреннего использования
//
Функция ПолучитьТекстЗапросаПоСтроке(СтрокаДереваМетаданных, ЕстьДопОтборы, СтрокаПолейДляВыборки = "",
	СтрокаПолейДляВыборки1 = "", ТаблицаОтбора1) Экспорт

	ОбъектМетаданных  = СтрокаДереваМетаданных.Метаданные;
	ИмяМетаданных     = ОбъектМетаданных.ПолноеИмя();

	Если Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных) Тогда

		ТекстЗапроса = ПолучитьТекстЗапросаДляРегистраСведений(ИмяМетаданных, ОбъектМетаданных, ЕстьДопОтборы,
			СтрокаПолейДляВыборки, СтрокаПолейДляВыборки1, ТаблицаОтбора1);
		Возврат ТекстЗапроса;

	ИначеЕсли Метаданные.РегистрыНакопления.Содержит(ОбъектМетаданных) Или Метаданные.РегистрыБухгалтерии.Содержит(
		ОбъектМетаданных) Тогда

		ТекстЗапроса = ПолучитьТекстЗапросаДляРегистра(ИмяМетаданных, ОбъектМетаданных, ЕстьДопОтборы,
			СтрокаПолейДляВыборки, ТаблицаОтбора1);
		Возврат ТекстЗапроса;

	КонецЕсли;

	ЕстьОграничениеПоДатам = (ЗначениеЗаполнено(ДатаНачала) Или ЗначениеЗаполнено(ДатаОкончания))
		И ИспользоватьОтборПоДатеДляВсехОбъектов;

	Если Не ЗначениеЗаполнено(СтрокаПолейДляВыборки) Тогда
		СтрокаПолейДляВыборки = "ТаблицаОбъекта_" + СтрокаДереваМетаданных.ПолноеИмяМетаданных + ".*";
	КонецЕсли;

	ТекстЗапроса = "ВЫБРАТЬ Разрешенные " + СтрокаПолейДляВыборки + " ИЗ " + ИмяМетаданных + " КАК ТаблицаОбъекта_"
		+ СтрокаДереваМетаданных.ПолноеИмяМетаданных;
	
	// возможно нужно ограничение по датам установить
	Первая=Истина;

	Если ЕстьОграничениеПоДатам Тогда

		Если ЕстьДопОтборы И Не ИспользоватьОтборПоДатеДляВсехОбъектов Тогда

			Возврат ТекстЗапроса;

		КонецЕсли;

		ДопОграничениеПоДате = "";
		
		// можно ли для данного объекта МД строить ограничения по датам
		Если Метаданные.Документы.Содержит(ОбъектМетаданных) Тогда

			ДопОграничениеПоДате = ПолучитьСтрокуОграниченияПоДатеДляЗапроса(ОбъектМетаданных, "Документ");
			Первая=Ложь;

		ИначеЕсли Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМетаданных) Или Метаданные.РегистрыНакопления.Содержит(
			ОбъектМетаданных) Тогда

			ДопОграничениеПоДате = ПолучитьСтрокуОграниченияПоДатеДляЗапроса(ОбъектМетаданных, "Регистр");
			Первая=Ложь;

		КонецЕсли;

		ТекстЗапроса = ТекстЗапроса + Символы.ПС + ДопОграничениеПоДате;
	КонецЕсли;

	Для Каждого Строка Из ТаблицаОтбора1 Цикл
		Если СтрокаДереваМетаданных.ПолноеИмяМетаданных = Строка.имяреквизита
			И СтрокаДереваМетаданных.Родитель.Метаданные = Строка.ИмяОбъектаМетаданных Тогда
			Для Каждого СтрокаЭлементы Из Строка.Отбор.Элементы Цикл
				Если СтрокаЭлементы.Использование Тогда

					Если Не Первая Тогда
						ТекстЗапроса = ТекстЗапроса + Символы.ПС + " И " + ПолучитьВидСравненияВЗапрос(Строка,
							СтрокаЭлементы, СтрокаЭлементы.ВидСравнения);
					Иначе
						ТекстЗапроса = ТекстЗапроса + Символы.ПС + " ГДЕ " + ПолучитьВидСравненияВЗапрос(Строка,
							СтрокаЭлементы, СтрокаЭлементы.ВидСравнения);
					КонецЕсли;
					Первая=Ложь;
				КонецЕсли;
			КонецЦикла;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	Возврат ТекстЗапроса;

КонецФункции
Функция ПолучитьВидСравненияВзапрос(Строка, СтрокаЭлементы, ВидСравнения)
	
	//Строка.ИмяРеквизита+ПолучитьВидСравненияВЗапрос(СтрокаЭлементы.ВидСравнения)+"&"+Строка(СтрокаЭлементы.ЛевоеЗначение)+ Символы.ПС

	ЛевоеЗначение=СтрЗаменить(Строка(СтрокаЭлементы.ЛевоеЗначение), ".", "_");

	Если ВидСравнения = ВидСравненияКомпоновкиданных.Больше Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + ">&"
			+ ЛевоеЗначение + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.БольшеИлиРавно Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + ">=&" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.ВИерархии Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + " В ИЕРАРХИИ(&"
			+ ЛевоеЗначение + ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.ВСписке Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + " В (&"
			+ ЛевоеЗначение + ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.ВСпискеПоИерархии Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + " В ИЕРАРХИИ(&"
			+ ЛевоеЗначение + ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Меньше Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + "<&"
			+ ЛевоеЗначение + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.МеньшеИлиРавно Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + "<=&"
			+ ЛевоеЗначение + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеВИерархии Тогда
		ВозвращЗначение=" НЕ " + "ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение
			+ " В ИЕРАРХИИ(&" + ЛевоеЗначение + ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеВСписке Тогда
		ВозвращЗначение=" НЕ " + "ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + " В (&"
			+ ЛевоеЗначение + ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеВСпискеПоИерархии Тогда
		ВозвращЗначение=" НЕ " + "ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение
			+ " В ИЕРАРХИИ(&" + ЛевоеЗначение + ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеРавно Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + "<>&"
			+ ЛевоеЗначение + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеСодержит Тогда
		ВозвращЗначение=" НЕ " + "ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение
			+ " ПОДОБНО &" + ЛевоеЗначение + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Подобно Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + " ПОДОБНО &"
			+ ЛевоеЗначение + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеПодобно Тогда
		ВозвращЗначение=" НЕ " + "ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение
			+ " ПОДОБНО &" + ЛевоеЗначение + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Равно Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + "=&"
			+ ЛевоеЗначение + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Содержит Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + " ПОДОБНО &"
			+ ЛевоеЗначение + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НачинаетсяС Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + ">=&"
			+ ЛевоеЗначение + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеНачинаетсяС Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + "<&"
			+ ЛевоеЗначение + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Заполнено Тогда
		ВозвращЗначение="ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение + " ЕСТЬ NULL "
			+ Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НЕЗаполнено Тогда
		ВозвращЗначение=" НЕ " + "ТаблицаОбъекта_" + Строка.ИмяРеквизита + "." + СтрокаЭлементы.ЛевоеЗначение
			+ " ЕСТЬ NULL " + Символы.ПС;
	КонецЕсли;

	Возврат ВозвращЗначение;

КонецФункции

Функция ПолучитьВидСравненияВзапросКонстанта(Строка, СтрокаЭлементы, ВидСравнения)
	
	//Строка.ИмяРеквизита+ПолучитьВидСравненияВЗапрос(СтрокаЭлементы.ВидСравнения)+"&"+Строка(СтрокаЭлементы.ЛевоеЗначение)+ Символы.ПС
	Если ВидСравнения = ВидСравненияКомпоновкиданных.Больше Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + ">&" + Строка(СтрокаЭлементы.ЛевоеЗначение)
			+ Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.БольшеИлиРавно Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + ">=&" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.ВИерархии Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + " В ИЕРАРХИИ(&" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.ВСписке Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + " В (&" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.ВСпискеПоИерархии Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + " В ИЕРАРХИИ(&" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Меньше Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + "<&" + Строка(СтрокаЭлементы.ЛевоеЗначение)
			+ Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.МеньшеИлиРавно Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + "<=&" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеВИерархии Тогда
		ВозвращЗначение=" НЕ " + Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + " В ИЕРАРХИИ(&" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеВСписке Тогда
		ВозвращЗначение=" НЕ " + Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение"" В (&" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеВСпискеПоИерархии Тогда
		ВозвращЗначение=" НЕ " + Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + " В ИЕРАРХИИ(&" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеРавно Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + "<>&" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеСодержит Тогда
		ВозвращЗначение=" НЕ " + Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + " ПОДОБНО &" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Подобно Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + " ПОДОБНО &" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеПодобно Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + " ПОДОБНО &" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Равно Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + "=&" + Строка(СтрокаЭлементы.ЛевоеЗначение)
			+ Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Содержит Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + " ПОДОБНО &" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НачинаетсяС Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + ">=&" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеНачинаетсяС Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + "<&" + Строка(СтрокаЭлементы.ЛевоеЗначение)
			+ Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Заполнено Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + " ЕСТЬ NULL " + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НЕЗаполнено Тогда
		ВозвращЗначение=" НЕ " + Строка(СтрокаЭлементы.ЛевоеЗначение) + ".Значение" + " ЕСТЬ NULL " + Символы.ПС;
	КонецЕсли;

	Возврат ВозвращЗначение;

КонецФункции

Функция ПолучитьВидСравненияВзапросРегистр(Строка, СтрокаЭлементы, ВидСравнения)
	
	//Строка.ИмяРеквизита+ПолучитьВидСравненияВЗапрос(СтрокаЭлементы.ВидСравнения)+"&"+Строка(СтрокаЭлементы.ЛевоеЗначение)+ Символы.ПС
	Если ВидСравнения = ВидСравненияКомпоновкиданных.Больше Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ">&" + Строка(СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.БольшеИлиРавно Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ">=&" + Строка(СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.ВИерархии Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + " В ИЕРАРХИИ(&" + Строка(СтрокаЭлементы.ЛевоеЗначение)
			+ ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.ВСписке Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + " В (&" + Строка(СтрокаЭлементы.ЛевоеЗначение) + ")"
			+ Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.ВСпискеПоИерархии Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + " В ИЕРАРХИИ(&" + Строка(СтрокаЭлементы.ЛевоеЗначение)
			+ ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Меньше Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + "<&" + Строка(СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.МеньшеИлиРавно Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + "<=&" + Строка(СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеВИерархии Тогда
		ВозвращЗначение=" НЕ " + СтрокаЭлементы.ЛевоеЗначение + " В ИЕРАРХИИ(&" + Строка(СтрокаЭлементы.ЛевоеЗначение)
			+ ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеВСписке Тогда
		ВозвращЗначение=" НЕ " + Строка(СтрокаЭлементы.ЛевоеЗначение) + " В (&" + Строка(СтрокаЭлементы.ЛевоеЗначение)
			+ ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеВСпискеПоИерархии Тогда
		ВозвращЗначение=" НЕ " + Строка(СтрокаЭлементы.ЛевоеЗначение) + " В ИЕРАРХИИ(&" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + ")" + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеРавно Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + "<>&" + Строка(СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеСодержит Тогда
		ВозвращЗначение=" НЕ " + Строка(СтрокаЭлементы.ЛевоеЗначение) + " ПОДОБНО &" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Подобно Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + " ПОДОБНО &" + Строка(СтрокаЭлементы.ЛевоеЗначение)
			+ Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеПодобно Тогда
		ВозвращЗначение=" НЕ " + Строка(СтрокаЭлементы.ЛевоеЗначение) + " ПОДОБНО &" + Строка(
			СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Равно Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + "=&" + Строка(СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Содержит Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + " ПОДОБНО &" + Строка(СтрокаЭлементы.ЛевоеЗначение)
			+ Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НачинаетсяС Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + ">=&" + Строка(СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НеНачинаетсяС Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + "<&" + Строка(СтрокаЭлементы.ЛевоеЗначение) + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.Заполнено Тогда
		ВозвращЗначение=Строка(СтрокаЭлементы.ЛевоеЗначение) + " ЕСТЬ NULL " + Символы.ПС;
	ИначеЕсли ВидСравнения = ВидСравненияКомпоновкиданных.НЕЗаполнено Тогда
		ВозвращЗначение=" НЕ " + Строка(СтрокаЭлементы.ЛевоеЗначение) + " ЕСТЬ NULL " + Символы.ПС;
	КонецЕсли;

	Возврат ВозвращЗначение;

КонецФункции



// Для внутреннего использования
//
Функция ПодготовитьПостроительДляВыгрузки(СтрокаДереваМетаданных, СтрокаПолейДляВыборки = "",
	СтрокаПолейДляВыборки1 = "", ТаблицаОтбора1) Экспорт

	ЕстьДопОтборы = (СтрокаДереваМетаданных.НастройкиПостроителя <> Неопределено);

	ИтоговыйТекстЗапроса = ПолучитьТекстЗапросаПоСтроке(СтрокаДереваМетаданных, ЕстьДопОтборы, СтрокаПолейДляВыборки,
		СтрокаПолейДляВыборки1, ТаблицаОтбора1);

	ПостроительОтчета = Новый ПостроительОтчета;

	ПостроительОтчета.Текст = ИтоговыйТекстЗапроса;

	ПостроительОтчета.ЗаполнитьНастройки();

	ПостроительОтчета.Отбор.Сбросить();
	Если ЕстьДопОтборы Тогда

		ПостроительОтчета.УстановитьНастройки(СтрокаДереваМетаданных.НастройкиПостроителя);

	КонецЕсли;

	ПостроительОтчета.Параметры.Вставить("ДатаНачала", ДатаНачала);
	ПостроительОтчета.Параметры.Вставить("ДатаОкончания", ДатаОкончания);

	Для Каждого СтрокаТабл Из ТаблицаОтбора1 Цикл
		Если СтрокаДереваМетаданных.Метаданные.Имя = СтрокаТабл.ИмяРеквизита И СтрокаТабл.ИмяОбъектаМетаданных
			= СтрокаДереваМетаданных.Родитель.Метаданные Тогда
			Для Каждого СтрокаЭлемент Из СтрокаТабл.Отбор.Элементы Цикл

				ЛевоеЗначение=СтрЗаменить(Строка(СтрокаЭлемент.ЛевоеЗначение), ".", "_");

				Если СтрокаЭлемент.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит Или СтрокаЭлемент.ВидСравнения
					= ВидСравненияКомпоновкиДанных.НеСодержит Тогда
					ПостроительОтчета.Параметры.Вставить(ЛевоеЗначение, "%" + СтрокаЭлемент.ПравоеЗначение + "%");
				Иначе
					Если Строка(ТипЗнч(СтрокаЭлемент.ПравоеЗначение)) = "Стандартная дата начала" Тогда
						ПостроительОтчета.Параметры.Вставить(ЛевоеЗначение, СтрокаЭлемент.ПравоеЗначение.Дата);
					Иначе
						ПостроительОтчета.Параметры.Вставить(ЛевоеЗначение, СтрокаЭлемент.ПравоеЗначение);
					КонецЕсли;
				КонецЕсли;

			КонецЦикла;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	Возврат ПостроительОтчета;

КонецФункции

Функция ПолучитьРезультатЗапросаСОграничениями(СтрокаДереваМетаданных, ТаблицаОтбора1)

	ПостроительОтчета = ПодготовитьПостроительДляВыгрузки(СтрокаДереваМетаданных, , , ТаблицаОтбора1);

	ПостроительОтчета.Выполнить();
	РезультатЗапроса = ПостроительОтчета.Результат;

	Возврат РезультатЗапроса;

КонецФункции

Процедура ЗаписьДанныхОбъектногоТипа(СтрокаДереваМетаданных, ЗаписьXML, ОбъектыВыгруженныеСОшибками,
	ТолькоПроверкаНедопустимыхСимволов = Ложь, ТаблицаОтбора1)

	РезультатЗапроса = ПолучитьРезультатЗапросаСОграничениями(СтрокаДереваМетаданных, ТаблицаОтбора1);

	ЗапросИЗапись(РезультатЗапроса, ЗаписьXML, Истина, ОбъектыВыгруженныеСОшибками, ТолькоПроверкаНедопустимыхСимволов);

КонецПроцедуры

// Процедура исполняет переданный запрос и записывает полученные через запрос объекты
//
// Параметры
//   Запрос - запрос для исполнения, результат содержит выборку объектов для записи
//   ЗаписьXML - объект, через которых происходит запись объектов ИБ
//   ЗапросВерхнегоУровня - признак необходимости анимации процесса
//
Процедура ЗапросИЗапись(РезультатЗапроса, ЗаписьXML, ЗапросВерхнегоУровня = Ложь, ОбъектыВыгруженныеСОшибками,
	ТолькоПроверкаНедопустимыхСимволов)
	
	// универсальная процедура выгрузки ссылочных объектов процедура
	ОбработкаРезультатаЗапроса(РезультатЗапроса, ЗаписьXML, Истина, ЗапросВерхнегоУровня, ОбъектыВыгруженныеСОшибками,
		ТолькоПроверкаНедопустимыхСимволов);

КонецПроцедуры

Процедура ВыполнитьВспомогательныеДействияДляЗаписиXML(ВсегоОбработаноОбъектов, ЗаписьXML,
	ТолькоПроверкаНедопустимыхСимволов)

	Если Не ТолькоПроверкаНедопустимыхСимволов Тогда
		Возврат;
	КонецЕсли;

	Если ВсегоОбработаноОбъектов > 1000 Тогда
		
		//@skip-warning
		СтрокаРезультата = ЗаписьXML.Закрыть();
		СтрокаРезультата = Неопределено;
		ЗаписьXML = Неопределено;

		ЗаписьXML = СоздатьОбъектЗаписиXMLДляПроверки();

	КонецЕсли;

КонецПроцедуры

Функция СсылкаВыгружена(Ссылка)

	Возврат мВыгруженныеОбъекты.Найти(Ссылка, "Ссылка") <> Неопределено;

КонецФункции

Процедура ДобавитьСсылкуКВыгруженным(Ссылка)

	СтрокаДобавления = мВыгруженныеОбъекты.Добавить();
	СтрокаДобавления.Ссылка = Ссылка;

КонецПроцедуры

// Процедура записывает содержащиеся в выборке результата запроса объекты и необходимые "по ссылке" объекты ИБ
//
// Параметры
//   РезультатЗапроса - результат запроса
//   ЗаписьXML - объект, через которых происходит запись объектов ИБ
//   ЭтоЗапросПоОбъекту - если Истина, выборка должна содержать объекты, на которые может быть ссылка,
//             если Ложь, выгружать, как объект не нужно, только обработать возможные ссылки на др. объекты ИБ
//
Процедура ОбработкаРезультатаЗапроса(РезультатЗапроса, ЗаписьXML, ЭтоЗапросПоОбъекту = Ложь,
	ЗапросВерхнегоУровня = Ложь, ОбъектыВыгруженныеСОшибками = Неопределено, ТолькоПроверкаНедопустимыхСимволов = Ложь)

	ВыборкаИзРезультатовЗапроса = РезультатЗапроса.Выбрать();

	ВсегоОбработаноОбъектов = 0;
//	ОбработаноОбъектов = 0;

	Пока ВыборкаИзРезультатовЗапроса.Следующий() Цикл

		Если ЭтоЗапросПоОбъекту Тогда
			
			// выгрузка ссылочных объектов
			Ссылка = ВыборкаИзРезультатовЗапроса.Ссылка;
			Если СсылкаВыгружена(Ссылка) Тогда

				Продолжить;

			КонецЕсли;

			ДобавитьСсылкуКВыгруженным(Ссылка);

			ВсегоОбработаноОбъектов = ВсегоОбработанныхЗаписей();

		КонецЕсли;

		Если мНаличиеВыгрузкиПодчиненныхОбъектов Тогда
		
			// перебираем колонки запроса в поисках ссылочных значений, которые, возможно, нужно выгрузить
			Для Каждого КолонкаЗапроса Из РезультатЗапроса.Колонки Цикл

				ЗначениеКолонки = ВыборкаИзРезультатовЗапроса[КолонкаЗапроса.Имя];

				Если ТипЗнч(ЗначениеКолонки) = мТипРезультатЗапроса Тогда

					ОбработкаРезультатаЗапроса(ЗначениеКолонки, ЗаписьXML, , , ОбъектыВыгруженныеСОшибками,
						ТолькоПроверкаНедопустимыхСимволов);

				Иначе

					ЗаписатьЗначениеПриНеобходимости(ЗначениеКолонки, ЗаписьXML, ОбъектыВыгруженныеСОшибками,
						ТолькоПроверкаНедопустимыхСимволов);

				КонецЕсли;

			КонецЦикла;

		КонецЕсли;

		Если ЭтоЗапросПоОбъекту Тогда

			Объект = Ссылка.ПолучитьОбъект();

			Попытка

				ВыполнитьВспомогательныеДействияДляЗаписиXML(ВсегоОбработаноОбъектов, ЗаписьXML,
					ТолькоПроверкаНедопустимыхСимволов);

				Сериализатор.ЗаписатьXML(ЗаписьXML, Объект);

				МетаданныеОбъекта = Объект.Метаданные();

				Если ЭтоМетаданныеСПредопределеннымиЭлементами(МетаданныеОбъекта) И Объект.Предопределенный Тогда

					НоваяСтрока = ТаблицаПредопределенных.Добавить();
					НоваяСтрока.ИмяТаблицы = МетаданныеОбъекта.ПолноеИмя();
					НоваяСтрока.Ссылка = XMLСтрока(Ссылка);
					НоваяСтрока.ИмяПредопределенныхДанных = Объект.ИмяПредопределенныхДанных;

				КонецЕсли;

				Если ВыгружатьСДокументомЕгоДвижения И Метаданные.Документы.Содержит(МетаданныеОбъекта) Тогда
					
					// выгрузка движений документа
					Для Каждого Движение Из Объект.Движения Цикл

						Движение.Прочитать();

						Если мНаличиеВыгрузкиПодчиненныхОбъектов И Движение.Количество() > 0 Тогда

							ТипРегистра = Тип(Движение);

							МассивКолонок = мСоответствиеКолонокДвижений.Получить(ТипРегистра);

							Если МассивКолонок = Неопределено Тогда

								ТаблицаДвижений = Движение.Выгрузить();
								РегистрБухгалтерии = Метаданные.РегистрыБухгалтерии.Содержит(Движение.Метаданные());
								МассивКолонок = ПолучитьМассивКолонокДвижения(ТаблицаДвижений, РегистрБухгалтерии);
								мСоответствиеКолонокДвижений.Вставить(ТипРегистра, МассивКолонок);

							КонецЕсли;

							ВыгрузитьПодчиненныеЗначенияНабора(ЗаписьXML, Движение, МассивКолонок,
								ОбъектыВыгруженныеСОшибками, ТолькоПроверкаНедопустимыхСимволов);

						КонецЕсли;

						Сериализатор.ЗаписатьXML(ЗаписьXML, Движение);

					КонецЦикла;

				КонецЕсли;

			Исключение

				СтрокаОписанияОшибки = ОписаниеОшибки();
				//не смогли записать в XML
				// возможно проблема с недопустимыми символами в XML
				Если ТолькоПроверкаНедопустимыхСимволов Тогда

					Если ОбъектыВыгруженныеСОшибками.Получить(Ссылка) = Неопределено Тогда
						ОбъектыВыгруженныеСОшибками.Вставить(Ссылка, СтрокаОписанияОшибки);
					КонецЕсли;

				Иначе

					ИтоговаяСтрокаСообщения = Нстр("ru = 'При выгрузке объекта %1(%2) возникла ошибка:
												   |%3'");
					ИтоговаяСтрокаСообщения = ПодставитьПараметрыВСтроку(ИтоговаяСтрокаСообщения, Объект, ТипЗнч(
						Объект), СтрокаОписанияОшибки);
					СообщитьПользователю(ИтоговаяСтрокаСообщения);

					ВызватьИсключение ИтоговаяСтрокаСообщения;

				КонецЕсли;

			КонецПопытки;

		КонецЕсли;

	КонецЦикла;

КонецПроцедуры

Процедура ВыгрузитьПодчиненныеЗначенияНабора(ЗаписьXML, Движение, МассивКолонок, ОбъектыВыгруженныеСОшибками,
	ТолькоПроверкаНедопустимыхСимволов)

	Для Каждого ЗаписьИзНабора Из Движение Цикл

		Для Каждого Колонка Из МассивКолонок Цикл

			Если Колонка = "СубконтоДт" Или Колонка = "СубконтоКт" Тогда

				Значение = ЗаписьИзНабора[Колонка];
				Для Каждого КлючИЗначение Из Значение Цикл

					Если ЗначениеЗаполнено(КлючИЗначение.Значение) Тогда
						ЗаписатьЗначениеПриНеобходимости(КлючИЗначение.Значение, ЗаписьXML,
							ОбъектыВыгруженныеСОшибками, ТолькоПроверкаНедопустимыхСимволов);
					КонецЕсли;

				КонецЦикла;

			Иначе

				СохраненноеЗначение = ЗаписьИзНабора[Колонка];
				ЗаписатьЗначениеПриНеобходимости(СохраненноеЗначение, ЗаписьXML, ОбъектыВыгруженныеСОшибками,
					ТолькоПроверкаНедопустимыхСимволов);

			КонецЕсли;

		КонецЦикла;

	КонецЦикла;

КонецПроцедуры

Функция ПолучитьМассивКолонокДвижения(ТаблицаДвижений, РегистрБухгалтерии = Ложь)

	МассивКолонок = Новый Массив;
	Для Каждого КолонкаТаблицы Из ТаблицаДвижений.Колонки Цикл

		Если КолонкаТаблицы.Имя = "МоментВремени" Или Найти(КолонкаТаблицы.Имя, "ВидСубконтоДт") = 1 Или Найти(
			КолонкаТаблицы.Имя, "ВидСубконтоКт") = 1 Тогда

			Продолжить;

		КонецЕсли;

		Если Найти(КолонкаТаблицы.Имя, "СубконтоДт") = 1 И РегистрБухгалтерии Тогда

			Если МассивКолонок.Найти("СубконтоДт") = Неопределено Тогда
				МассивКолонок.Добавить("СубконтоДт");
			КонецЕсли;

			Продолжить;

		КонецЕсли;

		Если Найти(КолонкаТаблицы.Имя, "СубконтоКт") = 1 И РегистрБухгалтерии Тогда

			Если МассивКолонок.Найти("СубконтоКт") = Неопределено Тогда
				МассивКолонок.Добавить("СубконтоКт");
			КонецЕсли;

			Продолжить;

		КонецЕсли;

		МассивКолонок.Добавить(КолонкаТаблицы.Имя);

	КонецЦикла;

	Возврат МассивКолонок;

КонецФункции

// Процедура анализирует необходимость записи объекта "по ссылке" и осуществляет запись
//
// Параметры
//   АнализируемоеЗначение - анализируемое значение
//   ЗаписьXML - объект, через которых происходит запись объектов ИБ
//
Процедура ЗаписатьЗначениеПриНеобходимости(АнализируемоеЗначение, ЗаписьXML, ОбъектыВыгруженныеСОшибками,
	ТолькоПроверкаНедопустимыхСимволов)

	Если Не ЗначениеЗаполнено(АнализируемоеЗначение) Тогда
		Возврат;
	КонецЕсли;

	ОбъектМД = СсылочныеТипы.Получить(ТипЗнч(АнализируемоеЗначение));

	Если ОбъектМД = Неопределено Тогда
		Возврат; // это не ссылка
	КонецЕсли;

	Если СсылкаВыгружена(АнализируемоеЗначение) Тогда
		Возврат; // объект уже был выгружен
	КонецЕсли;
	
	// Проверка того, что данный тип входит в список выгружаемых дополнительно
	СтрокаТаблицы = СоставПолнойВыгрузки.Найти(ОбъектМД, "ОбъектМД");
	Если СтрокаТаблицы <> Неопределено Тогда
		Возврат;
	КонецЕсли;

	СтрокаТаблицы = СоставВспомогательнойВыгрузки.Найти(ОбъектМД, "ОбъектМД");
	Если СтрокаТаблицы <> Неопределено Тогда

		ДопЗапрос = Новый Запрос("ВЫБРАТЬ * ИЗ " + СтрокаТаблицы.СтрокаДерева.ЭлементОписания.ДляЗапроса + ОбъектМД.Имя
			+ " КАК ТаблицаОбъекта_" + " ГДЕ Ссылка = &Ссылка");
		ДопЗапрос.УстановитьПараметр("Ссылка", АнализируемоеЗначение);
		РезультатЗапроса = ДопЗапрос.Выполнить();
		ЗапросИЗапись(РезультатЗапроса, ЗаписьXML, , ОбъектыВыгруженныеСОшибками, ТолькоПроверкаНедопустимыхСимволов);

	КонецЕсли;

КонецПроцедуры

// Процедура записывает значение константы
//
// Параметры
//   ЗаписьXML - объект, через которых происходит запись объектов ИБ
//   МД_Константа - описание метаданного - выгружаемой константы
//
Процедура ЗаписьКонстанты(ЗаписьXML, МД_Константа, ОбъектыВыгруженныеСОшибками, ТолькоПроверкаНедопустимыхСимволов,
	ТаблицаОтбора1)
	ТекстЗапроса= "ВЫБРАТЬ
				  |	АвтоматическиНастраиватьРазрешенияВПрофиляхБезопасности.Значение КАК Значение
				  |ИЗ
				  |	Константа.АвтоматическиНастраиватьРазрешенияВПрофиляхБезопасности КАК АвтоматическиНастраиватьРазрешенияВПрофиляхБезопасности
				  |";

	Первая=Истина;
	Найдено=Ложь;

	Для Каждого Строка Из ТаблицаОтбора1 Цикл
		Если МД_Константа.ИМЯ = Строка.имяреквизита Тогда
			Найдено=Истина;
			Для Каждого СтрокаЭлементы Из Строка.Отбор.Элементы Цикл
				Если СтрокаЭлементы.Использование Тогда
					Если Не Первая Тогда
						ТекстЗапроса = ТекстЗапроса + Символы.ПС + " И " + ПолучитьВидСравненияВЗапросКонстанта(Строка,
							СтрокаЭлементы, СтрокаЭлементы.ВидСравнения);
					Иначе
						ТекстЗапроса = ТекстЗапроса + Символы.ПС + " ГДЕ " + ПолучитьВидСравненияВЗапросКонстанта(
							Строка, СтрокаЭлементы, СтрокаЭлементы.ВидСравнения);
					КонецЕсли;
					Первая=Ложь;
				КонецЕсли;
			КонецЦикла;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	Выгружать=Ложь;
	Если Не найдено Тогда
		МенеджерЗначения = Константы[МД_Константа.Имя].СоздатьМенеджерЗначения();
		МенеджерЗначения.Прочитать();
		ЗаписатьЗначениеПриНеобходимости(МенеджерЗначения.Значение, ЗаписьXML, ОбъектыВыгруженныеСОшибками,
			ТолькоПроверкаНедопустимыхСимволов);
		Выгружать=Истина;
	Иначе

		Запрос=Новый запрос;
		Запрос.Текст=Текстзапроса;

		Для Каждого Строка Из ТаблицаОтбора1 Цикл
			Если МД_Константа.ИМЯ = Строка.имяреквизита Тогда
				Найдено=Истина;
				Для Каждого СтрокаЭлементы Из Строка.Отбор.Элементы Цикл
					Если СтрокаЭлементы.Использование Тогда
						Запрос.УстановитьПараметр(Строка.имяреквизита, СтрокаЭлементы.ПравоеЗначение);
					КонецЕсли;
				КонецЦикла;
				Прервать;
			КонецЕсли;
		КонецЦикла;
		Выборка1=Запрос.Выполнить().Выбрать();

		Пока Выборка1.Следующий() Цикл
			МенеджерЗначения = Константы[МД_Константа.Имя].СоздатьМенеджерЗначения();
			МенеджерЗначения.Прочитать();
			Если Выборка1.Значение = МенеджерЗначения.Значение Тогда
				ЗаписатьЗначениеПриНеобходимости(МенеджерЗначения.Значение, ЗаписьXML, ОбъектыВыгруженныеСОшибками,
					ТолькоПроверкаНедопустимыхСимволов);
				Выгружать=Истина;
			КонецЕсли;
		КонецЦикла;

	КонецЕсли;	
	// собственно выгрузка

	ВсегоОбработаноОбъектов = ВсегоОбработанныхЗаписей();
	Попытка
		Если Выгружать Тогда
			ВыполнитьВспомогательныеДействияДляЗаписиXML(ВсегоОбработаноОбъектов, ЗаписьXML,
				ТолькоПроверкаНедопустимыхСимволов);
			Сериализатор.ЗаписатьXML(ЗаписьXML, МенеджерЗначения);
		КонецЕсли;
	Исключение
		СтрокаОписанияОшибки = ОписаниеОшибки();
		//не смогли записать в XML
		// возможно проблема с недопустимыми символами в XML
		Если ТолькоПроверкаНедопустимыхСимволов Тогда
			ОбъектыВыгруженныеСОшибками.Вставить(МенеджерЗначения, СтрокаОписанияОшибки);
		Иначе
			ИтоговаяСтрокаСообщения = Нстр("ru = 'При выгрузке константы %1 возникла ошибка:
										   |%2'");
			ИтоговаяСтрокаСообщения = ПодставитьПараметрыВСтроку(ИтоговаяСтрокаСообщения, МД_Константа.Имя,
				СтрокаОписанияОшибки);

			СообщитьПользователю(ИтоговаяСтрокаСообщения);
			ВызватьИсключение ИтоговаяСтрокаСообщения;
		КонецЕсли;

	КонецПопытки;

	ОбработанныхКонстант = ОбработанныхКонстант + 1;

КонецПроцедуры

// Процедура записывает наборы записей регистра (накопления, бухгалтерии...)
//
// Параметры
//   ЗаписьXML - объект, через которых происходит запись объектов ИБ
//   СтрокаДереваМетаданных - строка дерева метаданных, соответствующая регистру
//
Процедура ЗаписьРегистра(ЗаписьXML, СтрокаДереваМетаданных, ОбъектыВыгруженныеСОшибками,
	ТолькоПроверкаНедопустимыхСимволов, РегистрБухгалтерии = Ложь, ТаблицаОтбора1)

	МенеджерНабораЗаписей = СтрокаДереваМетаданных.ЭлементОписания.Менеджер[СтрокаДереваМетаданных.ОбъектМД.Имя];

	ИмяТаблицыДляЗапроса = СтрокаДереваМетаданных.ЭлементОписания.ДляЗапроса;

	ЗаписьЧерезНаборЗаписей(ЗаписьXML, МенеджерНабораЗаписей, ИмяТаблицыДляЗапроса,
		СтрокаДереваМетаданных.ОбъектМД.Имя, СтрокаДереваМетаданных, ОбъектыВыгруженныеСОшибками,
		ТолькоПроверкаНедопустимыхСимволов, РегистрБухгалтерии, ТаблицаОтбора1);

КонецПроцедуры

// Процедура записывает наборы записей регистра (накопления, бухгалтерии...)
//
// Параметры
//   ЗаписьXML - объект, через которых происходит запись объектов ИБ
//   СтрокаДереваМетаданных - строка дерева метаданных, соответствующая регистру
//
Процедура ЗаписьПерерасчета(ЗаписьXML, СтрокаДереваМетаданных, ОбъектыВыгруженныеСОшибками,
	ТолькоПроверкаНедопустимыхСимволов, ТаблицаОтбора1)

	ИмяРегистраРасчета = СтрокаДереваМетаданных.Родитель.Родитель.ОбъектМД.Имя;
	МенеджерСтрокой = СтрЗаменить(СтрокаДереваМетаданных.ЭлементОписания.Менеджер, "%i", ИмяРегистраРасчета);
	МенеджерПерерасчета = Вычислить(МенеджерСтрокой);
	МенеджерПерерасчета = МенеджерПерерасчета[СтрокаДереваМетаданных.ОбъектМД.Имя];
	СтрокаДляЗапроса = СтрЗаменить(СтрокаДереваМетаданных.ЭлементОписания.ДляЗапроса, "%i", ИмяРегистраРасчета);

	ЗаписьЧерезНаборЗаписей(ЗаписьXML, МенеджерПерерасчета, СтрокаДляЗапроса, СтрокаДереваМетаданных.ОбъектМД.Имя,
		СтрокаДереваМетаданных, ОбъектыВыгруженныеСОшибками, ТолькоПроверкаНедопустимыхСимволов, , ТаблицаОтбора1);

КонецПроцедуры

// Процедура записывает последовательности документов
//
// Параметры
//   ЗаписьXML - объект, через которых происходит запись объектов ИБ
//   СтрокаДереваМетаданных - строка дерева метаданных, соответствующая регистру
//
Процедура ЗаписьПоследовательности(ЗаписьXML, СтрокаДереваМетаданных, ОбъектыВыгруженныеСОшибками,
	ТолькоПроверкаНедопустимыхСимволов, ТаблицаОтбора1)

	МенеджерНабораЗаписей = СтрокаДереваМетаданных.ЭлементОписания.Менеджер[СтрокаДереваМетаданных.ОбъектМД.Имя];

	ЗаписьЧерезНаборЗаписей(ЗаписьXML, МенеджерНабораЗаписей, СтрокаДереваМетаданных.ЭлементОписания.ДляЗапроса,
		СтрокаДереваМетаданных.ОбъектМД.Имя, СтрокаДереваМетаданных, ОбъектыВыгруженныеСОшибками,
		ТолькоПроверкаНедопустимыхСимволов, , ТаблицаОтбора1);

КонецПроцедуры

// Процедура записывает данные, доступ к которым осуществляется через набор записей
//
// Параметры
//   ЗаписьXML - объект, через которых происходит запись объектов ИБ
//   СтрокаДереваМетаданных - строка дерева метаданных, соответствующая регистру
//
Процедура ЗаписьЧерезНаборЗаписей(ЗаписьXML, МенеджерНабораЗаписей, ДляЗапроса, ИмяОбъекта,
	СтрокаДереваМетаданных = Неопределено, ОбъектыВыгруженныеСОшибками, ТолькоПроверкаНедопустимыхСимволов,
	РегистрБухгалтерии = Ложь, ТаблицаОтбора1)
	
	// получить состав колонок записи регистра и проверить наличие хотя бы одной записи
	Если ДляЗапроса = "РегистрБухгалтерии." Тогда
		ИмяТаблицыДляЗапроса = ДляЗапроса + ИмяОбъекта + ".ДвиженияССубконто";
	Иначе
		ИмяТаблицыДляЗапроса = ДляЗапроса + ИмяОбъекта;
	КонецЕсли;

	Первая=Истина;
	Запрос= Новый Запрос;

	Если ДляЗапроса = "РегистрБухгалтерии." Тогда

		УсловиеЗапроса="";
		//  ограничения
		Для Каждого Строка Из ТаблицаОтбора1 Цикл
			Если ИмяОбъекта = Строка.имяреквизита И СтрокаДереваМетаданных.ИмяОбъектаМетаданных
				= Строка.ИмяОбъектаМетаданных Тогда
				Для Каждого СтрокаЭлементы Из Строка.Отбор.Элементы Цикл
					Если СтрокаЭлементы.Использование Тогда

						Если Строка(ТипЗнч(СтрокаЭлементы.ПравоеЗначение)) = "Стандартная дата начала" Тогда
							Запрос.УстановитьПараметр(Строка(СтрокаЭлементы.ЛевоеЗначение),
								СтрокаЭлементы.ПравоеЗначение.Дата);
						Иначе
							Запрос.УстановитьПараметр(Строка(СтрокаЭлементы.ЛевоеЗначение),
								СтрокаЭлементы.ПравоеЗначение);
						КонецЕсли;

						Если Не Первая Тогда
							УсловиеЗапроса = УсловиеЗапроса + Символы.ПС + " И " + ПолучитьВидСравненияВЗапросРегистр(
								Строка, СтрокаЭлементы, СтрокаЭлементы.ВидСравнения);
						Иначе
							УсловиеЗапроса = УсловиеЗапроса + Символы.ПС + " " + ПолучитьВидСравненияВЗапросРегистр(
								Строка, СтрокаЭлементы, СтрокаЭлементы.ВидСравнения);
						КонецЕсли;
						Первая=Ложь;
					КонецЕсли;
				КонецЦикла;
				Прервать;
			КонецЕсли;
		КонецЦикла;
		ТекстЗапроса="ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ  1 * ИЗ " + ИмяТаблицыДляЗапроса + "(, , " + УсловиеЗапроса
			+ ", ,  )  КАК ТаблицаОбъекта_" + ИмяОбъекта;

	Иначе

		ТекстЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ  1 *   ИЗ " + ИмяТаблицыДляЗапроса + " КАК ТаблицаОбъекта_"
			+ ИмяОбъекта;

		Для Каждого Строка Из ТаблицаОтбора1 Цикл
			Если ИмяОбъекта = Строка.имяреквизита И СтрокаДереваМетаданных.ИмяОбъектаМетаданных
				= Строка.ИмяОбъектаМетаданных Тогда
				Для Каждого СтрокаЭлементы Из Строка.Отбор.Элементы Цикл
					Если СтрокаЭлементы.Использование Тогда

						Если Строка(ТипЗнч(СтрокаЭлементы.ПравоеЗначение)) = "Стандартная дата начала" Тогда
							Запрос.УстановитьПараметр(Строка(СтрокаЭлементы.ЛевоеЗначение),
								СтрокаЭлементы.ПравоеЗначение.Дата);
						Иначе
							Запрос.УстановитьПараметр(Строка(СтрокаЭлементы.ЛевоеЗначение),
								СтрокаЭлементы.ПравоеЗначение);
						КонецЕсли;

						Если Не Первая Тогда
							ТекстЗапроса = ТекстЗапроса + Символы.ПС + " И " + ПолучитьВидСравненияВЗапрос(Строка,
								СтрокаЭлементы, СтрокаЭлементы.ВидСравнения);
						Иначе
							ТекстЗапроса = ТекстЗапроса + Символы.ПС + " ГДЕ " + ПолучитьВидСравненияВЗапрос(Строка,
								СтрокаЭлементы, СтрокаЭлементы.ВидСравнения);
						КонецЕсли;
						Первая=Ложь;
					КонецЕсли;
				КонецЦикла;
				Прервать;
			КонецЕсли;
		КонецЦикла;

	КонецЕсли;
	Запрос.Текст=ТекстЗапроса;

	РезультатЗапросаПоСоставу = Запрос.Выполнить();
	Если РезультатЗапросаПоСоставу.Пустой() Тогда
		Возврат;
	КонецЕсли;

	ТаблицаДвижений = РезультатЗапросаПоСоставу.Выгрузить();
	МассивКолонок = ПолучитьМассивКолонокДвижения(ТаблицаДвижений, РегистрБухгалтерии);
	
	// выгрузка регистров осуществляется через его набор записей
	НаборЗаписей = МенеджерНабораЗаписей.СоздатьНаборЗаписей();

	Отбор = НаборЗаписей.Отбор;
	СтрокаПолейОтбора = "";
	Для Каждого ЭлементОтбора Из Отбор Цикл
		Если Не ПустаяСтрока(СтрокаПолейОтбора) Тогда
			СтрокаПолейОтбора = СтрокаПолейОтбора + ",";
		КонецЕсли;
		СтрокаПолейОтбора =СтрокаПолейОтбора + "ТаблицаОбъекта_" + ИмяОбъекта + "." + ЭлементОтбора.Имя;
	КонецЦикла;

	СтрокаПолейОтбора1 = "";
	Для Каждого ЭлементОтбора Из Отбор Цикл
		Если Не ПустаяСтрока(СтрокаПолейОтбора1) Тогда
			СтрокаПолейОтбора1 = СтрокаПолейОтбора1 + ",";
		КонецЕсли;
		СтрокаПолейОтбора1 =СтрокаПолейОтбора1 + "ТаблицаОбъекта_" + ИмяОбъекта + "1." + ЭлементОтбора.Имя;
	КонецЦикла;

	ПостроительОтчета = ПодготовитьПостроительДляВыгрузки(СтрокаДереваМетаданных, СтрокаПолейОтбора, СтрокаПолейОтбора1,
		ТаблицаОтбора1);
	ПостроительОтчета.Выполнить();
	РезультатЗапросаПоЗначениямОтбора = ПостроительОтчета.Результат;
	ВыборкаИзРезультата = РезультатЗапросаПоЗначениямОтбора.Выбрать();

	КоличествоПолейОтбора = НаборЗаписей.Отбор.Количество();
	
	// читаем наборы записей с различным составом отбора и записываем их
	Пока ВыборкаИзРезультата.Следующий() Цикл
		
		// Отбор устанавливаем для регистров, у которых есть хотя бы один отбор (измерение)
		Если КоличествоПолейОтбора <> 0 Тогда

			Для Каждого Колонка Из РезультатЗапросаПоЗначениямОтбора.Колонки Цикл
				Отбор[Колонка.Имя].Значение = ВыборкаИзРезультата[Колонка.Имя];
				Отбор[Колонка.Имя].ВидСравнения = ВидСравнения.Равно;
				Отбор[Колонка.Имя].Использование = Истина;
			КонецЦикла;

		КонецЕсли;

		НаборЗаписей.Прочитать();

		Если мНаличиеВыгрузкиПодчиненныхОбъектов Тогда
		
			// проверяем все записанные в наборе значения на необходимость записи "по ссылке"
			ВыгрузитьПодчиненныеЗначенияНабора(ЗаписьXML, НаборЗаписей, МассивКолонок, ОбъектыВыгруженныеСОшибками,
				ТолькоПроверкаНедопустимыхСимволов);

		КонецЕсли;

		ВсегоОбработаноОбъектов = ВсегоОбработанныхЗаписей();
		Попытка

			ВыполнитьВспомогательныеДействияДляЗаписиXML(ВсегоОбработаноОбъектов, ЗаписьXML,
				ТолькоПроверкаНедопустимыхСимволов);

			Сериализатор.ЗаписатьXML(ЗаписьXML, НаборЗаписей);

		Исключение

			СтрокаОписанияОшибки = ОписаниеОшибки();
			//не смогли записать в XML
			// возможно проблема с недопустимыми символами в XML
			Если ТолькоПроверкаНедопустимыхСимволов Тогда

				НовыйНабор = МенеджерНабораЗаписей.СоздатьНаборЗаписей();

				Для Каждого СтрокаОтбора Из НаборЗаписей.Отбор Цикл

					СтрокаОтбораФормы = НовыйНабор.Отбор.Найти(СтрокаОтбора.Имя);

					Если СтрокаОтбораФормы = Неопределено Тогда
						Продолжить;
					КонецЕсли;

					СтрокаОтбораФормы.Использование = СтрокаОтбора.Использование;
					СтрокаОтбораФормы.ВидСравнения = СтрокаОтбора.ВидСравнения;
					СтрокаОтбораФормы.Значение = СтрокаОтбора.Значение;

				КонецЦикла;

				ОбъектыВыгруженныеСОшибками.Вставить(НовыйНабор, СтрокаОписанияОшибки);

			Иначе

				ИтоговаяСтрокаСообщения = Нстр("ru = 'При выгрузке регистра %1%2 возникла ошибка:
											   |%3'");
				ИтоговаяСтрокаСообщения = ПодставитьПараметрыВСтроку(ИтоговаяСтрокаСообщения, ДляЗапроса, ИмяОбъекта,
					СтрокаОписанияОшибки);

				СообщитьПользователю(ИтоговаяСтрокаСообщения);

				ВызватьИсключение ИтоговаяСтрокаСообщения;

			КонецЕсли;

		КонецПопытки;

		ОбработанныхНаборовЗаписей = ОбработанныхНаборовЗаписей + 1;

	КонецЦикла;

КонецПроцедуры

// Процедура рекурсивно обрабатывает строку дерева метаданных, образуя списки полной и вспомогательной выгрузки
//
// Параметры
//   СоставПолнойВыгрузки - список полной выгрузки
//   СоставВспомогательнойВыгрузки - список вспомогательной выгрузки
//   СтрокаДЗ - обрабатываемая строка дерева метаданных
//
Процедура ДобавитьВыгружаемыеОбъекты(СоставПолнойВыгрузки, СоставВспомогательнойВыгрузки, СтрокаДЗ)

	Если (СтрокаДЗ.ЭлементОписания <> Неопределено) И СтрокаДЗ.ЭлементОписания.Выгружаемый Тогда

		СтрокаДобавления = Неопределено;

		Если СтрокаДЗ.Выгружать Тогда

			СтрокаДобавления = СоставПолнойВыгрузки.Добавить();

		ИначеЕсли СтрокаДЗ.ВыгружатьПриНеобходимости Тогда

			СтрокаДобавления = СоставВспомогательнойВыгрузки.Добавить();

		КонецЕсли;

		Если СтрокаДобавления <> Неопределено Тогда

			СтрокаДобавления.ОбъектМД = СтрокаДЗ.ОбъектМД;
			СтрокаДобавления.СтрокаДерева = СтрокаДЗ;

		КонецЕсли;

	КонецЕсли;

	Для Каждого ПодчиненнаяСтрокаДЗ Из СтрокаДЗ.Строки Цикл
		ДобавитьВыгружаемыеОбъекты(СоставПолнойВыгрузки, СоставВспомогательнойВыгрузки, ПодчиненнаяСтрокаДЗ);
	КонецЦикла;

КонецПроцедуры

// Процедура заполняет строку дерева метаданных, попутно заполняя соответствие ссылочных типов объектам метаданных
//
// Параметры
//   ОбъектМД - описание объекта метаданных
//   ЭлементДЗ - заполняемая строка дерева метаданных
//   ЭлементОписания - описание класса, к которому принадлежит объект метаданных (свойства, подчиненные классы)
//
Процедура ПостроениеПоддереваОбъекта(ОбъектМД, ЭлементДЗ, ЭлементОписания)

	ЭлементДЗ.Метаданные = ОбъектМД;
	ЭлементДЗ.ОбъектМД   = ОбъектМД;
	ЭлементДЗ.ПолноеИмяМетаданных = ОбъектМД.Имя;
	ЭлементДЗ.ИмяОбъектаМетаданных= ЭлементОписания.Класс;

	ЭлементДЗ.ЭлементОписания = ЭлементОписания;
	ЭлементДЗ.Выгружать = Ложь;
	ЭлементДЗ.ВыгружатьПриНеобходимости = Истина;
	ЭлементДЗ.ИндексКартинки = ЭлементОписания.ИндексКартинки;
	//ЭлементДЗ.ИндексВДереве=НомерСтрокидерева;
	//НомерСтрокидерева=НомерСтрокидерева+1;

	Если ЭлементОписания.Менеджер <> Неопределено Тогда
		
		// заполнение соответствия ссылочных типов объектам метаданных
		Если ОбъектОбразуетСсылочныйТип(ОбъектМД) Тогда
			СсылочныеТипы[ТипЗнч(ЭлементОписания.Менеджер[ОбъектМД.Имя].ПустаяСсылка())] = ОбъектМД;
		КонецЕсли;

		Если Метаданные.РегистрыНакопления.Содержит(ОбъектМД) Или Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМД) Тогда

			ИспользующиеИтоги.Добавить(ЭлементДЗ);

		КонецЕсли;

	КонецЕсли;		
		
	// подчиненные ветви
	Для Каждого ПодчиненныйКласс Из ЭлементОписания.Строки Цикл

		Если Не ПодчиненныйКласс.Выгружаемый Тогда
			Продолжить;
		КонецЕсли;

		ВеткаКласса = ЭлементДЗ.Строки.Добавить();
		ВеткаКласса.Метаданные = ПодчиненныйКласс.Класс;
		ВеткаКласса.Выгружать = Ложь;
		ВеткаКласса.ВыгружатьПриНеобходимости = Истина;
		ВеткаКласса.ПолноеИмяМетаданных = ПодчиненныйКласс.Класс;
		ВеткаКласса.ИндексКартинки = ПодчиненныйКласс.ИндексКартинки;

		ПодчиненныеОбъектыДанногоКласса = ОбъектМД[ПодчиненныйКласс.Класс];

		Для Каждого ПодчиненныйОбъектМД Из ПодчиненныеОбъектыДанногоКласса Цикл
			ПодчиненныйЭлементДЗ = ВеткаКласса.Строки.Добавить();
			ПостроениеПоддереваОбъекта(ПодчиненныйОбъектМД, ПодчиненныйЭлементДЗ, ПодчиненныйКласс);
		КонецЦикла;

	КонецЦикла;

КонецПроцедуры

// Процедура удаляет из дерева метаданных строки, соответствующие метаданным, заведомо не попадающим в выгрузку
//
// Параметры
//   ЭлементДЗ - строка дерева метаданных, подчиненные которой рассматриваются
//        с точки зрения удаления из списка потенциально выгружаемых
//
Процедура СверткаПоддереваОбъекта(ЭлементДЗ)

	УдаляемыеВеткиКлассов = Новый Массив;
	Для Каждого ВеткаКласса Из ЭлементДЗ.Строки Цикл

		УдаляемыеПодчиненныеМД = Новый Массив;

		Для Каждого ПодчиненныйОбъектМД Из ВеткаКласса.Строки Цикл
			СверткаПоддереваОбъекта(ПодчиненныйОбъектМД);
			Если (ПодчиненныйОбъектМД.Строки.Количество()) = 0 И (Не ПодчиненныйОбъектМД.ЭлементОписания.Выгружаемый) Тогда

				УдаляемыеПодчиненныеМД.Добавить(ВеткаКласса.Строки.Индекс(ПодчиненныйОбъектМД));

			КонецЕсли;

		КонецЦикла;

		Для Сч = 1 По УдаляемыеПодчиненныеМД.Количество() Цикл
			ВеткаКласса.Строки.Удалить(УдаляемыеПодчиненныеМД[УдаляемыеПодчиненныеМД.Количество() - Сч]);
		КонецЦикла;

		Если ВеткаКласса.Строки.Количество() = 0 Тогда
			УдаляемыеВеткиКлассов.Добавить(ЭлементДЗ.Строки.Индекс(ВеткаКласса));
		КонецЕсли;

	КонецЦикла;

	Для Сч = 1 По УдаляемыеВеткиКлассов.Количество() Цикл
		ЭлементДЗ.Строки.Удалить(УдаляемыеВеткиКлассов[УдаляемыеВеткиКлассов.Количество() - Сч]);
	КонецЦикла;

КонецПроцедуры

// Процедура проставляет признак Выгрузка строкам дерева метаданных, подчиненных данной, вычисляет и 
//      выставляет признак выгрузки "по ссылке" другим объектам, ссылки на которые может или должен
//      содержать объект, соответствующий данной строке
//
// Параметры
//   ЭлементДЗ - строка дерева метаданных
//
Процедура УстановитьВыгружатьПодчиненным(ЭлементДЗ)
	Для Каждого ПодчиненнаяСтрока Из ЭлементДЗ.Строки Цикл
		ПодчиненнаяСтрока.Выгружать = ЭлементДЗ.Выгружать;
		УстановитьВыгружатьПодчиненным(ПодчиненнаяСтрока);
	КонецЦикла;
КонецПроцедуры

// Процедура проставляет признак Выгрузка строке дерева метаданных на основании этого признака подчиненных строк,
// затем вызывает себя же для родителя, обеспечивая отработку до корня дерева
//
// Параметры
//   ЭлементДЗ - строка дерева метаданных
//
Процедура ОбновитьСостояниеВыгружать(ЭлементДЗ)
	Если ЭлементДЗ = Неопределено Тогда
		Возврат;
	КонецЕсли;
	Если (ЭлементДЗ.ЭлементОписания <> Неопределено) И ЭлементДЗ.ЭлементОписания.Выгружаемый Тогда
		Возврат; // обновляем вверх или до корня, или до первого встретившегося выгружаемого
	КонецЕсли;
	Состояние = Неопределено;
	Для Каждого ПодчиненныйЭлементДЗ Из ЭлементДЗ.Строки Цикл
		Если Состояние = Неопределено Тогда
			Состояние = ПодчиненныйЭлементДЗ.Выгружать;
		Иначе
			Если Не Состояние = ПодчиненныйЭлементДЗ.Выгружать Тогда
				Состояние = 2;
				Прервать;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;

	Если Состояние <> Неопределено Тогда
		ЭлементДЗ.Выгружать = Состояние;
		ОбновитьСостояниеВыгружать(ЭлементДЗ.Родитель);
	КонецЕсли;
КонецПроцедуры

// Процедура обрабатывает состояние признака Выгрузка, проставляя признаки Выгрузка и ВыгружатьПриНеобходимости
// связанным ветвям дерева
//
// Параметры
//   ЭлементДЗ - строка дерева метаданных
//
Процедура ОбработкаИзмененияСостоянияВыгружать(ЭлементДЗ) Экспорт
	Если ЭлементДЗ.Выгружать = 2 Тогда
		ЭлементДЗ.Выгружать = 0;
	КонецЕсли;
	// Изменяем состояние "вниз"
	УстановитьВыгружатьПодчиненным(ЭлементДЗ);
	// Изменяем состояние "вверх"
	ОбновитьСостояниеВыгружать(ЭлементДЗ.Родитель);
КонецПроцедуры

// Процедура проставляет признак Выгрузка строкам дерева метаданных, подчиненных данной, вычисляет и 
//      выставляет признак выгрузки "по ссылке" другим объектам, ссылки на которые может или должен
//      содержать объект, соответствующий данной строке
//
// Параметры
//   ЭлементДЗ - строка дерева метаданных
//
Процедура УстановитьВыгружатьПриНеобходимостиПодчиненным(ЭлементДЗ)

	Для Каждого ПодчиненнаяСтрока Из ЭлементДЗ.Строки Цикл
		ПодчиненнаяСтрока.ВыгружатьПриНеобходимости = ЭлементДЗ.ВыгружатьПриНеобходимости;
		УстановитьВыгружатьПриНеобходимостиПодчиненным(ПодчиненнаяСтрока);
	КонецЦикла;

КонецПроцедуры

// Процедура проставляет признак Выгрузка строке дерева метаданных на основании этого признака подчиненных строк,
// затем вызывает себя же для родителя, обеспечивая отработку до корня дерева
//
// Параметры
//   ЭлементДЗ - строка дерева метаданных
//
Процедура ОбновитьСостояниеВыгружатьПриНеобходимости(ЭлементДЗ)

	Если ЭлементДЗ = Неопределено Тогда
		Возврат;
	КонецЕсли;

	Если (ЭлементДЗ.ЭлементОписания <> Неопределено) И ЭлементДЗ.ЭлементОписания.Выгружаемый Тогда
		Возврат; // обновляем вверх или до корня, или до первого встретившегося выгружаемого
	КонецЕсли;

	Состояние = Неопределено;
	Для Каждого ПодчиненныйЭлементДЗ Из ЭлементДЗ.Строки Цикл

		Если Состояние = Неопределено Тогда
			Состояние = ПодчиненныйЭлементДЗ.ВыгружатьПриНеобходимости;
		Иначе
			Если Не Состояние = ПодчиненныйЭлементДЗ.ВыгружатьПриНеобходимости Тогда
				Состояние = 2;
				Прервать;
			КонецЕсли;
		КонецЕсли;

	КонецЦикла;

	Если Состояние <> Неопределено Тогда
		ЭлементДЗ.ВыгружатьПриНеобходимости = Состояние;
		ОбновитьСостояниеВыгружатьПриНеобходимости(ЭлементДЗ.Родитель);
	КонецЕсли;

КонецПроцедуры

// Процедура обрабатывает состояние признака Выгрузка, проставляя признаки Выгрузка и ВыгружатьПриНеобходимости
// связанным ветвям дерева
//
// Параметры
//   ЭлементДЗ - строка дерева метаданных
//
Процедура ОбработкаИзмененияСостоянияВыгружатьПриНеобходимости(ЭлементДЗ) Экспорт

	Если ЭлементДЗ.ВыгружатьПриНеобходимости = 2 Тогда
		ЭлементДЗ.ВыгружатьПриНеобходимости = 0;
	КонецЕсли;
	
	// Изменяем состояние "вниз"
	УстановитьВыгружатьПриНеобходимостиПодчиненным(ЭлементДЗ);
	// Изменяем состояние "вверх"
	ОбновитьСостояниеВыгружатьПриНеобходимости(ЭлементДЗ.Родитель);

КонецПроцедуры

// Функция определяет, являются ли объекты данного класса метаданных типизированными
//
// Параметры
//   Описание - Описание класса
// Возврат - Истина, если объекты данного класса метаданных типизированы, Ложь в противном случае
//
Функция КлассМДТипизированный(Описание)

	Для Каждого Свойство Из Описание.Свойства Цикл
		Если Свойство.Значение = "Тип" Тогда
			Возврат Истина;
		КонецЕсли;
	КонецЦикла;
	Возврат Ложь;

КонецФункции

// Функция определяет, являются ли тип ссылочным
//
// Параметры
//   Тип - исследуемый тип
// Возврат - Истина, если тип ссылочный, Ложь в противном случае
//
Функция СсылочныйТип(Тип)

	МетаданныеТипа = СсылочныеТипы.Получить(Тип);
	Возврат МетаданныеТипа <> Неопределено;

КонецФункции

// Процедура добавляет в массив новый элемент, если он является уникальным
//
// Параметры
//   Массив - исследуемый тип
//   Элемент - добавляемый элемент
//
Процедура ДобавитьВМассивЕслиУникальный(Массив, Элемент)

	Если Массив.Найти(Элемент) = Неопределено Тогда
		Массив.Добавить(Элемент);
	КонецЕсли;

КонецПроцедуры

// Функция возвращает массив типов, которые могут иметь поля записи объекта метаданных, соответствующего строке дерева
//
// Параметры
//   ЭлементДЗ - строка дерева метаданных
// Возврат - массив потенциально используемых соответствующей записью типов
//
Функция ПолучитьВсеТипы(ЭлементДЗ)

	ОбъектМД = ЭлементДЗ.ОбъектМД;
	Если ТипЗнч(ОбъектМД) <> Тип("ОбъектМетаданных") И ТипЗнч(ОбъектМД) <> Тип("ОбъектМетаданныхКонфигурация") Тогда

		ВызватьИсключение (Нстр("ru = 'Внутренняя ошибка обработки выгрузки'"));

	КонецЕсли;

	Возврат ПолучитьТипыИспользуемыеОМД(ОбъектМД, ЭлементДЗ.ЭлементОписания);

КонецФункции

// Функция возвращает массив типов, которые могут иметь поля записи объекта метаданных
//
// Параметры
//   ОбъектМД - описание метаданного
//   ЭлементОписания - описание класса объекта метаданного
// Возврат - массив потенциально используемых соответствующей записью типов
//
Функция ПолучитьТипыИспользуемыеОМД(ОбъектМД, ЭлементОписания)

	ВсеТипы = Новый Массив;

	Для Каждого Свойство Из ЭлементОписания.Свойства Цикл

		ЗначениеСвойства = ОбъектМД[Свойство.Значение];
		Если ТипЗнч(ЗначениеСвойства) = Тип("КоллекцияЗначенийСвойстваОбъектаМетаданных")
			И ЗначениеСвойства.Количество() > 0 Тогда

			Для Каждого СтрокаКоллекции Из ЗначениеСвойства Цикл

				СсылочныйТипКлючИЗначение = СоответствиеОбъектовМетаданныхИСсылочныхТипов[СтрокаКоллекции];

				Если СсылочныйТипКлючИЗначение <> Неопределено Тогда

					ДобавитьВМассивЕслиУникальный(ВсеТипы, СсылочныйТипКлючИЗначение);

				КонецЕсли;

			КонецЦикла;

		ИначеЕсли ТипЗнч(ЗначениеСвойства) = Тип("ОбъектМетаданных") Тогда

			Для Каждого СсылочныйТипКлючИЗначение Из СсылочныеТипы Цикл

				Если ЗначениеСвойства = СсылочныйТипКлючИЗначение.Значение Тогда
					ДобавитьВМассивЕслиУникальный(ВсеТипы, СсылочныйТипКлючИЗначение.Ключ);
				КонецЕсли;

			КонецЦикла;

		КонецЕсли;

	КонецЦикла;

	Если КлассМДТипизированный(ЭлементОписания) Тогда

		ОписаниеТипа = ОбъектМД.Тип;
		Для Каждого ОдинТип Из ОписаниеТипа.Типы() Цикл

			Если СсылочныйТип(ОдинТип) Тогда
				ДобавитьВМассивЕслиУникальный(ВсеТипы, ОдинТип);
			КонецЕсли;

		КонецЦикла;

	Иначе

		Если Метаданные.РегистрыСведений.Содержит(ОбъектМД) Или Метаданные.РегистрыНакопления.Содержит(ОбъектМД)
			Или Метаданные.РегистрыБухгалтерии.Содержит(ОбъектМД) Или Метаданные.РегистрыРасчета.Содержит(ОбъектМД) Тогда
			
			// какой-то из регистров, ищем в возможных регистраторах
			Для Каждого ДокументМД Из Метаданные.Документы Цикл

				Если ДокументМД.Движения.Содержит(ОбъектМД) Тогда

					ДобавитьВМассивЕслиУникальный(ВсеТипы, ТипЗнч(Документы[ДокументМД.Имя].ПустаяСсылка()));

				КонецЕсли;

			КонецЦикла;

		КонецЕсли;

	КонецЕсли;

	Для Каждого ПодчиненныйКласс Из ЭлементОписания.Строки Цикл

		Для Каждого ПодчиненныйОбъектМД Из ОбъектМД[ПодчиненныйКласс.Класс] Цикл

			ТипыПодчиненного = ПолучитьТипыИспользуемыеОМД(ПодчиненныйОбъектМД, ПодчиненныйКласс);
			Для Каждого ОдинТип Из ТипыПодчиненного Цикл
				ДобавитьВМассивЕслиУникальный(ВсеТипы, ОдинТип);
			КонецЦикла;

		КонецЦикла;

	КонецЦикла;

	Возврат ВсеТипы;

КонецФункции

// Функция возвращает строку дерева метаданных, соответствующую переданному объекту метаданных
// Поиск осуществляется среди строк, подчиненных переданной
//
// Параметры
//   СтрокаДЗ - строка дерева метаданных, от которой осуществляется поиск
//   ОбъектМД - описание метаданного
// Возврат - строка дерева метаданных
//
Функция ЭлементДЗПоОбъектуМДИСтроке(СтрокаДЗ, ОбъектМД)

	Возврат СтрокаДЗ.Строки.Найти(ОбъектМД, "ОбъектМД", Истина);

КонецФункции

// Функция возвращает строку дерева метаданных, соответствующую переданному объекту метаданных
// Поиск осуществляется по всему дереву метаданных
//
// Параметры
//   ОбъектМД - описание метаданного
// Возврат - строка дерева метаданных
//
Функция ЭлементДЗПоОбъектуМД(ОбъектМД)
	Для Каждого СтрокаДЗ Из ДеревоМетаданных.Строки Цикл
		ЭлементДЗ = ЭлементДЗПоОбъектуМДИСтроке(СтрокаДЗ, ОбъектМД);
		Если ЭлементДЗ <> Неопределено Тогда
			Возврат ЭлементДЗ;
		КонецЕсли;
	КонецЦикла;
	Возврат Неопределено;
КонецФункции

// Процедура определяет, на какие объект может ссылаться запись, соответствующая объекту метаданных, отображаемому
// данной строкой дерева метаданных и проставляет им признак ВыгружатьПриНеобходимости
//
// Параметры
//   ЭлементДЗ - строка дерева метаданных
//
Процедура УстановкаСостоянияВыгружатьПриНеобходимости(ЭлементДЗ)

	ОбновитьСостояниеВыгружатьПриНеобходимости(ЭлементДЗ.Родитель);
	Если ЭлементДЗ.Выгружать <> 1 И ЭлементДЗ.ВыгружатьПриНеобходимости <> 1 Тогда
		Возврат;
	КонецЕсли;
	Если ЭлементДЗ.ОбъектМД = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ВсеТипы = ПолучитьВсеТипы(ЭлементДЗ);
	Для Каждого СсылочныйТип Из ВсеТипы Цикл

		ТипИОбъект = СсылочныеТипы.Получить(СсылочныйТип);
		Если ТипИОбъект = Неопределено Тогда

			ТекстИсключения = Нстр("ru = 'Внутренняя ошибка. Неполное заполнение структуры ссылочных типов %1'");
			ТекстИсключения = ПодставитьПараметрыВСтроку(ТекстИсключения, СсылочныйТип);
			ВызватьИсключение (ТекстИсключения);

		КонецЕсли;

		ОбъектМД = ТипИОбъект;
		СтрокаДЗ = ЭлементДЗПоОбъектуМД(ОбъектМД);
		Если СтрокаДЗ = Неопределено Тогда

			ТекстИсключения = Нстр(
				"ru = 'Внутренняя ошибка. Неполное заполнение дерева метаданных. Отсутствует объект, образующий тип %1'");
			ТекстИсключения = ПодставитьПараметрыВСтроку(ТекстИсключения, СсылочныйТип);
			ВызватьИсключение (ТекстИсключения);

		КонецЕсли;

		Если СтрокаДЗ.Выгружать = 1 Или СтрокаДЗ.ВыгружатьПриНеобходимости = 1 Тогда

			Продолжить;

		КонецЕсли;

		СтрокаДЗ.ВыгружатьПриНеобходимости = 1;
		УстановкаСостоянияВыгружатьПриНеобходимости(СтрокаДЗ);

	КонецЦикла;

КонецПроцедуры

// Функция определяет общее количество произведенных записей констант + объектного типа + наборов записей
//
// Возврат - общее количество произведенных записей
Функция ВсегоОбработанныхЗаписей()

	Возврат мВыгруженныеОбъекты.Количество() + ОбработанныхКонстант + ОбработанныхНаборовЗаписей;

КонецФункции

// Процедура производит заполнение дерева описания классов объектов метаданных
//
// Параметры
//
Процедура ЗаполнитьОписаниеМетаданных()

	СтэкДереваЗначенийСтроки = Новый Массив;
	МетаданныеОписание = Новый ДеревоЗначений;
	МетаданныеОписание.Колонки.Добавить("Выгружаемый", Новый ОписаниеТипов("Булево"));
	МетаданныеОписание.Колонки.Добавить("ДляЗапроса", Новый ОписаниеТипов("Строка"));
	МетаданныеОписание.Колонки.Добавить("Класс", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100,
		ДопустимаяДлина.Переменная)));
	МетаданныеОписание.Колонки.Добавить("Менеджер");
	МетаданныеОписание.Колонки.Добавить("Свойства", Новый ОписаниеТипов("СписокЗначений"));
	МетаданныеОписание.Колонки.Добавить("ИндексКартинки");
	СтэкДереваЗначенийСтроки.Вставить(0, МетаданныеОписание.Строки);
	//////////////////////////////////
	// Конфигурации
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Конфигурации";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.ИндексКартинки = 0;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.Константы
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Константы";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = Константы;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.ИндексКартинки = 1;
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.Справочники
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Справочники";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = Справочники;
	ОписаниеКласса.ДляЗапроса  = "Справочник.";
	ОписаниеКласса.Свойства.Добавить("Владельцы");
	ОписаниеКласса.Свойства.Добавить("ВводитсяНаОсновании");
	ОписаниеКласса.ИндексКартинки = 3;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.Справочники.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	ОписаниеКласса.Свойства.Добавить("Использование");
	//////////////////////////////////
	// Конфигурации.Справочники.ТабличныеЧасти
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "ТабличныеЧасти";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Использование");
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.Справочники.ТабличныеЧасти.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	СтэкДереваЗначенийСтроки.Удалить(0);
	СтэкДереваЗначенийСтроки.Удалить(0);
	//////////////////////////////////
	// Конфигурации.Документы
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Документы";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = Документы;
	ОписаниеКласса.ДляЗапроса  = "Документ.";
	ОписаниеКласса.Свойства.Добавить("ВводитсяНаОсновании");
	ОписаниеКласса.Свойства.Добавить("Движения");
	ОписаниеКласса.ИндексКартинки = 7;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.Документы.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.Документы.ТабличныеЧасти
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "ТабличныеЧасти";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.Документы.ТабличныеЧасти.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	СтэкДереваЗначенийСтроки.Удалить(0);
	СтэкДереваЗначенийСтроки.Удалить(0);
	//////////////////////////////////
	// Конфигурации.Последовательности
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Последовательности";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = Последовательности;
	ОписаниеКласса.ДляЗапроса  = "Последовательность.";
	ОписаниеКласса.Свойства.Добавить("Документы");
	ОписаниеКласса.Свойства.Добавить("Движения");
	ОписаниеКласса.ИндексКартинки = 5;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.Последовательности.Измерения
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Измерения";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	ОписаниеКласса.Свойства.Добавить("СоответствиеДокументам");
	ОписаниеКласса.Свойства.Добавить("СоответствиеДвижениям");
	СтэкДереваЗначенийСтроки.Удалить(0);
	//////////////////////////////////
	// Конфигурации.ПланыВидовХарактеристик
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "ПланыВидовХарактеристик";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = ПланыВидовХарактеристик;
	ОписаниеКласса.ДляЗапроса  = "ПланВидовХарактеристик.";
	ОписаниеКласса.Свойства.Добавить("ДополнительныеЗначенияХарактеристик");
	ОписаниеКласса.Свойства.Добавить("Тип");
	ОписаниеКласса.Свойства.Добавить("ВводитсяНаОсновании");
	ОписаниеКласса.ИндексКартинки = 9;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.ПланыВидовХарактеристик.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	ОписаниеКласса.Свойства.Добавить("Использование");
	//////////////////////////////////
	// Конфигурации.ПланыВидовХарактеристик.ТабличныеЧасти
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "ТабличныеЧасти";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Использование");
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.ПланыВидовХарактеристик.ТабличныеЧасти.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	СтэкДереваЗначенийСтроки.Удалить(0);
	СтэкДереваЗначенийСтроки.Удалить(0);
	//////////////////////////////////
	// Конфигурации.ПланыСчетов
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "ПланыСчетов";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = ПланыСчетов;
	ОписаниеКласса.ДляЗапроса  = "ПланСчетов.";
	ОписаниеКласса.Свойства.Добавить("ВводитсяНаОсновании");
	ОписаниеКласса.Свойства.Добавить("ВидыСубконто");
	ОписаниеКласса.ИндексКартинки = 11;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.ПланыСчетов.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.ПланыСчетов.ТабличныеЧасти
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "ТабличныеЧасти";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.ПланыСчетов.ТабличныеЧасти.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	СтэкДереваЗначенийСтроки.Удалить(0);
	СтэкДереваЗначенийСтроки.Удалить(0);
	//////////////////////////////////
	// Конфигурации.ПланыВидовРасчета
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "ПланыВидовРасчета";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = ПланыВидовРасчета;
	ОписаниеКласса.ДляЗапроса  = "ПланВидовРасчета.";
	ОписаниеКласса.Свойства.Добавить("ВводитсяНаОсновании");
	ОписаниеКласса.Свойства.Добавить("ЗависимостьОтВидовРасчета");
	ОписаниеКласса.Свойства.Добавить("БазовыеВидыРасчета");
	ОписаниеКласса.Свойства.Добавить("ИспользованиеПериодаДействия");
	ОписаниеКласса.ИндексКартинки = 13;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.ПланыВидовРасчета.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.ПланыВидовРасчета.ТабличныеЧасти
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "ТабличныеЧасти";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.ПланыВидовРасчета.ТабличныеЧасти.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	СтэкДереваЗначенийСтроки.Удалить(0);
	СтэкДереваЗначенийСтроки.Удалить(0);
	//////////////////////////////////
	// Конфигурации.РегистрыСведений
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "РегистрыСведений";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = РегистрыСведений;
	ОписаниеКласса.ДляЗапроса  = "РегистрСведений.";
	ОписаниеКласса.ИндексКартинки = 15;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.РегистрыСведений.Ресурсы
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Ресурсы";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.РегистрыСведений.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.РегистрыСведений.Измерения
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Измерения";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	СтэкДереваЗначенийСтроки.Удалить(0);
	//////////////////////////////////
	// Конфигурации.РегистрыНакопления
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "РегистрыНакопления";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = РегистрыНакопления;
	ОписаниеКласса.ДляЗапроса  = "РегистрНакопления.";
	ОписаниеКласса.ИндексКартинки = 17;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.РегистрыНакопления.Ресурсы
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Ресурсы";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.РегистрыНакопления.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.РегистрыНакопления.Измерения
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Измерения";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	СтэкДереваЗначенийСтроки.Удалить(0);
	//////////////////////////////////
	// Конфигурации.РегистрыБухгалтерии
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "РегистрыБухгалтерии";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = РегистрыБухгалтерии;
	ОписаниеКласса.ДляЗапроса  = "РегистрБухгалтерии.";
	ОписаниеКласса.Свойства.Добавить("ПланСчетов");
	ОписаниеКласса.Свойства.Добавить("Корреспонденция");
	ОписаниеКласса.ИндексКартинки = 19;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.РегистрыБухгалтерии.Измерения
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Измерения";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.РегистрыБухгалтерии.Ресурсы
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Ресурсы";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.РегистрыБухгалтерии.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	СтэкДереваЗначенийСтроки.Удалить(0);
	//////////////////////////////////
	// Конфигурации.РегистрыРасчета
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "РегистрыРасчета";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = РегистрыРасчета;
	ОписаниеКласса.ДляЗапроса  = "РегистрРасчета.";
	ОписаниеКласса.Свойства.Добавить("Периодичность");
	ОписаниеКласса.Свойства.Добавить("ПериодДействия");
	ОписаниеКласса.Свойства.Добавить("БазовыйПериод");
	ОписаниеКласса.Свойства.Добавить("График");
	ОписаниеКласса.Свойства.Добавить("ЗначениеГрафика");
	ОписаниеКласса.Свойства.Добавить("ДатаГрафика");
	ОписаниеКласса.Свойства.Добавить("ПланВидовРасчета");
	ОписаниеКласса.ИндексКартинки = 21;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.РегистрыРасчета.Ресурсы
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Ресурсы";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.РегистрыРасчета.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	ОписаниеКласса.Свойства.Добавить("СвязьСГрафиком");
	//////////////////////////////////
	// Конфигурации.РегистрыРасчета.Измерения
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Измерения";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	ОписаниеКласса.Свойства.Добавить("БазовоеИзмерение");
	ОписаниеКласса.Свойства.Добавить("СвязьСГрафиком");
	//////////////////////////////////
	// Конфигурации.РегистрыРасчета.Перерасчеты
	//ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	//ОписаниеКласса.Класс = "Перерасчеты";
	//ОписаниеКласса.Выгружаемый = истина;
	//ОписаниеКласса.Менеджер  = "РегистрыРасчета.%i.Перерасчеты";
	//ОписаниеКласса.ДляЗапроса  = "РегистрРасчета.%i.";
	//СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.РегистрыРасчета.Перерасчеты.Измерения
	//ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	//ОписаниеКласса.Класс = "Измерения";
	//ОписаниеКласса.Выгружаемый = ложь;
	//ОписаниеКласса.Свойства.Добавить("ДанныеВедущихРегистров");
	//ОписаниеКласса.Свойства.Добавить("ИзмерениеРегистра");
	//СтэкДереваЗначенийСтроки.Удалить(0);
	СтэкДереваЗначенийСтроки.Удалить(0);
	//////////////////////////////////
	// Конфигурации.БизнесПроцессы
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "БизнесПроцессы";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = БизнесПроцессы;
	ОписаниеКласса.ДляЗапроса  = "БизнесПроцесс.";
	ОписаниеКласса.Свойства.Добавить("ВводитсяНаОсновании");
	ОписаниеКласса.Свойства.Добавить("Задача");
	ОписаниеКласса.ИндексКартинки = 23;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.БизнесПроцессы.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.БизнесПроцессы.ТабличныеЧасти
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "ТабличныеЧасти";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.БизнесПроцессы.ТабличныеЧасти.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	СтэкДереваЗначенийСтроки.Удалить(0);
	СтэкДереваЗначенийСтроки.Удалить(0);
	//////////////////////////////////
	// Конфигурации.Задачи
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Задачи";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = Задачи;
	ОписаниеКласса.ДляЗапроса  = "Задача.";
	ОписаниеКласса.Свойства.Добавить("Адресация");
	ОписаниеКласса.Свойства.Добавить("ОсновнойРеквизитАдресации");
	ОписаниеКласса.Свойства.Добавить("ТекущийИсполнитель");
	ОписаниеКласса.Свойства.Добавить("ВводитсяНаОсновании");
	ОписаниеКласса.ИндексКартинки = 25;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.Задачи.РеквизитыАдресации
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "РеквизитыАдресации";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	ОписаниеКласса.Свойства.Добавить("ИзмерениеАдресации");
	//////////////////////////////////
	// Конфигурации.Задачи.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.Задачи.ТабличныеЧасти
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "ТабличныеЧасти";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.Задачи.ТабличныеЧасти.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	СтэкДереваЗначенийСтроки.Удалить(0);
	СтэкДереваЗначенийСтроки.Удалить(0);
	
	//////////////////////////////////
	// Конфигурации.ПланыОбмена
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "ПланыОбмена";
	ОписаниеКласса.Выгружаемый = Истина;
	ОписаниеКласса.Менеджер = ПланыОбмена;
	ОписаниеКласса.ДляЗапроса  = "ПланОбмена.";
	ОписаниеКласса.Свойства.Добавить("ВводитсяНаОсновании");
	ОписаниеКласса.ИндексКартинки = 27;
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.ПланыОбмена.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	//////////////////////////////////
	// Конфигурации.ПланыОбмена.ТабличныеЧасти
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "ТабличныеЧасти";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	СтэкДереваЗначенийСтроки.Вставить(0, ОписаниеКласса.Строки);
	//////////////////////////////////
	// Конфигурации.ПланыОбмена.ТабличныеЧасти.Реквизиты
	ОписаниеКласса = СтэкДереваЗначенийСтроки[0].Добавить();
	ОписаниеКласса.Класс = "Реквизиты";
	ОписаниеКласса.Выгружаемый = Ложь;
	ОписаниеКласса.ДляЗапроса  = "";
	ОписаниеКласса.Свойства.Добавить("Тип");
	СтэкДереваЗначенийСтроки.Удалить(0);
	СтэкДереваЗначенийСтроки.Удалить(0);

	СтэкДереваЗначенийСтроки.Удалить(0);

КонецПроцедуры

// Функция определяет имеет ли переданный объект метаданных ссылочный тип
//
// Возврат - Истина, если переданный объект метаданных имеет ссылочный тип, Ложь - противном случае
Функция ОбъектОбразуетСсылочныйТип(ОбъектМД) Экспорт

	Если ОбъектМД = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;

	Если Метаданные.Справочники.Содержит(ОбъектМД) Или Метаданные.Документы.Содержит(ОбъектМД)
		Или Метаданные.ПланыВидовХарактеристик.Содержит(ОбъектМД) Или Метаданные.ПланыСчетов.Содержит(ОбъектМД)
		Или Метаданные.ПланыВидовРасчета.Содержит(ОбъектМД) Или Метаданные.ПланыОбмена.Содержит(ОбъектМД)
		Или Метаданные.БизнесПроцессы.Содержит(ОбъектМД) Или Метаданные.Задачи.Содержит(ОбъектМД) Тогда
		Возврат Истина;
	КонецЕсли;

	Возврат Ложь;
КонецФункции

// Процедура определяет, какие типы объектов следует выгружать для сохранения ссылочной целостности
//
// Параметры
//   Выгрузка - массив строк - совокупность выгружаемых объектов
Процедура ПересчитатьВыгружаемыеПоСсылке(Выгрузка)
	
	// сброс всех флажков ВыгружатьПриНеобходимости
	СтрокаКонфигурации = ДеревоМетаданных.Строки[0];
	СтрокаКонфигурации.ВыгружатьПриНеобходимости = 0;
	ОбработкаИзмененияСостоянияВыгружатьПриНеобходимости(СтрокаКонфигурации);
	
	// обработка переданного набора объектов
	Для Каждого Выгружаемый Из Выгрузка Цикл

		УстановкаСостоянияВыгружатьПриНеобходимости(Выгружаемый.СтрокаДерева);

	КонецЦикла;

КонецПроцедуры

// Процедура, при необходимости, устанавливает отсутствие необходимости использования итогов
//
// Параметры
Процедура УбратьИспользованиеИтогов() Экспорт

	Если ВключитьВозможностьРедактированияИспользованияИтогов Тогда

		Для Каждого Регистр_СДЗ Из ИспользующиеИтоги Цикл

			Регистр_СДЗ.ЭлементОписания.Менеджер[Регистр_СДЗ.ОбъектМД.Имя].УстановитьИспользованиеИтогов(Ложь);

		КонецЦикла;

	КонецЕсли;

КонецПроцедуры

// Процедура, при необходимости, устанавливает необходимость использования итогов
//
// Параметры
Процедура ВосстановитьИспользованиеИтогов() Экспорт

	Если ВключитьВозможностьРедактированияИспользованияИтогов Тогда

		Для Каждого Регистр_СДЗ Из ИспользующиеИтоги Цикл

			Регистр_СДЗ.ЭлементОписания.Менеджер[Регистр_СДЗ.ОбъектМД.Имя].УстановитьИспользованиеИтогов(Истина);

		КонецЦикла;

	КонецЕсли;

КонецПроцедуры

// Возвращает текущее значение версии обработки
//
// Параметры:
//  Нет.
// 
// Возвращаемое значение:
//  Текущее значение версии обработки
//
Функция ВерсияОбъекта() Экспорт

	Возврат "2.1.8";

КонецФункции

Процедура СообщитьПользователю(Текст)

	Сообщение = Новый СообщениеПользователю;
	Сообщение.Текст = Текст;
	Сообщение.Сообщить();

КонецПроцедуры

Процедура ИнициализироватьТаблицуПредопределенных()

	ТаблицаПредопределенных = Новый ТаблицаЗначений;
	ТаблицаПредопределенных.Колонки.Добавить("ИмяТаблицы");
	ТаблицаПредопределенных.Колонки.Добавить("Ссылка");
	ТаблицаПредопределенных.Колонки.Добавить("ИмяПредопределенныхДанных");

КонецПроцедуры

Процедура ВыгрузитьТаблицуПредопределенных(ЗаписьXML)

	ЗаписьXML.ЗаписатьНачалоЭлемента("PredefinedData");

	Если ТаблицаПредопределенных.Количество() > 0 Тогда

		ТаблицаПредопределенных.Сортировать("ИмяТаблицы");

		ИмяПредыдущейТаблицы = "";

		Для Каждого Элемент Из ТаблицаПредопределенных Цикл

			Если ИмяПредыдущейТаблицы <> Элемент.ИмяТаблицы Тогда
				Если Не ПустаяСтрока(ИмяПредыдущейТаблицы) Тогда
					ЗаписьXML.ЗаписатьКонецЭлемента();
				КонецЕсли;
				ЗаписьXML.ЗаписатьНачалоЭлемента(Элемент.ИмяТаблицы);
			КонецЕсли;

			ЗаписьXML.ЗаписатьНачалоЭлемента("item");
			ЗаписьXML.ЗаписатьАтрибут("Ссылка", Элемент.Ссылка);
			ЗаписьXML.ЗаписатьАтрибут("ИмяПредопределенныхДанных", Элемент.ИмяПредопределенныхДанных);
			ЗаписьXML.ЗаписатьКонецЭлемента();

			ИмяПредыдущейТаблицы = Элемент.ИмяТаблицы;

		КонецЦикла;

		ЗаписьXML.ЗаписатьКонецЭлемента();

	КонецЕсли;

	ЗаписьXML.ЗаписатьКонецЭлемента();

КонецПроцедуры

Процедура ЗагрузитьТаблицуПредопределенных(ЧтениеXML)

	ЧтениеXML.Пропустить(); // При первом чтении пропускам основной блок данных
	ЧтениеXML.Прочитать();

	ИнициализироватьТаблицуПредопределенных();
	ВременнаяСтрока = ТаблицаПредопределенных.Добавить();

	СоответствиеЗаменыСсылок = Новый Соответствие;

	Пока ЧтениеXML.Прочитать() Цикл

		Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда

			Если ЧтениеXML.ЛокальноеИмя <> "item" Тогда

				ВременнаяСтрока.ИмяТаблицы = ЧтениеXML.ЛокальноеИмя;

				ТекстЗапроса = "ВЫБРАТЬ 
							   |	Таблица.Ссылка КАК Ссылка
							   |ИЗ
							   |	" + ВременнаяСтрока.ИмяТаблицы + " КАК Таблица
																	 |ГДЕ
																	 |	Таблица.ИмяПредопределенныхДанных = &ИмяПредопределенныхДанных";
				Запрос = Новый Запрос(ТекстЗапроса);

			Иначе

				Пока ЧтениеXML.ПрочитатьАтрибут() Цикл

					ВременнаяСтрока[ЧтениеXML.ЛокальноеИмя] = ЧтениеXML.Значение;

				КонецЦикла;

				Запрос.УстановитьПараметр("ИмяПредопределенныхДанных", ВременнаяСтрока.ИмяПредопределенныхДанных);

				РезультатЗапроса = Запрос.Выполнить();
				Если Не РезультатЗапроса.Пустой() Тогда

					Выборка = РезультатЗапроса.Выбрать();

					Если Выборка.Количество() = 1 Тогда

						Выборка.Следующий();

						СсылкаВБазе = XMLСтрока(Выборка.Ссылка);
						СсылкаВФайле = ВременнаяСтрока.Ссылка;

						Если ЭтотОбъект.РежимЗагрузкиПредопределенных = 1 Тогда

							ОбъектУдаляемый=Выборка.Ссылка.ПолучитьОбъект();
							ОбъектУдаляемый.Удалить();

						Иначе

							Если СсылкаВБазе <> СсылкаВФайле Тогда

								XMLТип = XMLТипСсылки(Выборка.Ссылка);

								СоответствиеТипа = СоответствиеЗаменыСсылок.Получить(XMLТип);

								Если СоответствиеТипа = Неопределено Тогда

									СоответствиеТипа = Новый Соответствие;
									СоответствиеТипа.Вставить(СсылкаВФайле, СсылкаВБазе);
									СоответствиеЗаменыСсылок.Вставить(XMLТип, СоответствиеТипа);

								Иначе

									СоответствиеТипа.Вставить(СсылкаВФайле, СсылкаВБазе);

								КонецЕсли;

							КонецЕсли;

						КонецЕсли;

					Иначе

						ТекстИсключения = НСтр(
							"ru = 'Обнаружено дублирование предопределенных элементов %1 в таблице %2!'");
						ТекстИсключения = СтрЗаменить(ТекстИсключения, "%1", ВременнаяСтрока.ИмяПредопределенныхДанных);
						ТекстИсключения = СтрЗаменить(ТекстИсключения, "%2", ВременнаяСтрока.ИмяТаблицы);

						ВызватьИсключение ТекстИсключения;

					КонецЕсли;

				КонецЕсли;

			КонецЕсли;

		КонецЕсли;

	КонецЦикла;

	ЧтениеXML.Закрыть();

КонецПроцедуры

Процедура ЗаменитьСсылкиНаПредопределенные(ИмяФайла)

	ПотокЧтения = Новый ЧтениеТекста(ИмяФайла);

	ВременныйФайл = ПолучитьИмяВременногоФайла("xml");

	ПотокЗаписи = Новый ЗаписьТекста(ВременныйФайл);
	
	// Константы для разбора текста
	НачалоТипа = "xsi:type=""v8:";
	ДлинаНачалаТипа = СтрДлина(НачалоТипа);
	КонецТипа = """>";
	ДлинаКонцаТипа = СтрДлина(КонецТипа);

	ИсходнаяСтрока = ПотокЧтения.ПрочитатьСтроку();
	Пока ИсходнаяСтрока <> Неопределено Цикл

		ОстатокСтроки = Неопределено;

		ТекущаяПозиция = 1;
		ПозицияТипа = Найти(ИсходнаяСтрока, НачалоТипа);
		Пока ПозицияТипа > 0 Цикл

			ПотокЗаписи.Записать(Сред(ИсходнаяСтрока, ТекущаяПозиция, ПозицияТипа - 1 + ДлинаНачалаТипа));

			ОстатокСтроки = Сред(ИсходнаяСтрока, ТекущаяПозиция + ПозицияТипа + ДлинаНачалаТипа - 1);
			ТекущаяПозиция = ТекущаяПозиция + ПозицияТипа + ДлинаНачалаТипа - 1;

			ПозицияКонцаТипа = Найти(ОстатокСтроки, КонецТипа);
			Если ПозицияКонцаТипа = 0 Тогда
				Прервать;
			КонецЕсли;

			ИмяТипа = Лев(ОстатокСтроки, ПозицияКонцаТипа - 1);
			СоответствиеЗамены = СоответствиеЗаменыСсылок.Получить(ИмяТипа);
			Если СоответствиеЗамены = Неопределено Тогда
				ПозицияТипа = Найти(ОстатокСтроки, НачалоТипа);
				Продолжить;
			КонецЕсли;

			ПотокЗаписи.Записать(ИмяТипа);
			ПотокЗаписи.Записать(КонецТипа);

			ИсходнаяСсылкаXML = Сред(ОстатокСтроки, ПозицияКонцаТипа + ДлинаКонцаТипа, 36);

			НайденнаяСсылкаXML = СоответствиеЗамены.Получить(ИсходнаяСсылкаXML);

			Если НайденнаяСсылкаXML = Неопределено Тогда
				ПотокЗаписи.Записать(ИсходнаяСсылкаXML);
			Иначе
				ПотокЗаписи.Записать(НайденнаяСсылкаXML);
			КонецЕсли;

			ТекущаяПозиция = ТекущаяПозиция + ПозицияКонцаТипа - 1 + ДлинаКонцаТипа + 36;
			ОстатокСтроки = Сред(ОстатокСтроки, ПозицияКонцаТипа + ДлинаКонцаТипа + 36);
			ПозицияТипа = Найти(ОстатокСтроки, НачалоТипа);

		КонецЦикла;

		Если ОстатокСтроки <> Неопределено Тогда
			ПотокЗаписи.ЗаписатьСтроку(ОстатокСтроки);
		Иначе
			ПотокЗаписи.ЗаписатьСтроку(ИсходнаяСтрока);
		КонецЕсли;

		ИсходнаяСтрока = ПотокЧтения.ПрочитатьСтроку();

	КонецЦикла;

	ПотокЧтения.Закрыть();
	ПотокЗаписи.Закрыть();

	ИмяФайла = ВременныйФайл;

КонецПроцедуры

Функция ЭтоМетаданныеСПредопределеннымиЭлементами(ОбъектМетаданных)

	Возврат Метаданные.Справочники.Содержит(ОбъектМетаданных) Или Метаданные.ПланыСчетов.Содержит(ОбъектМетаданных)
		Или Метаданные.ПланыВидовХарактеристик.Содержит(ОбъектМетаданных) Или Метаданные.ПланыВидовРасчета.Содержит(
		ОбъектМетаданных);

КонецФункции

// Возвращает СериализаторXDTO с аннотацией типов.
//
// Возвращаемое значение:
//	СериализаторXDTO - сериализатор.
//
Процедура ИнициализироватьСериализаторXDTOСАннотациейТипов()

	ТипыСАннотациейСсылок = ПредопределенныеТипыПриВыгрузке();

	Если ТипыСАннотациейСсылок.Количество() > 0 Тогда

		Фабрика = ПолучитьФабрикуСУказаниемТипов(ТипыСАннотациейСсылок);
		Сериализатор = Новый СериализаторXDTO(Фабрика);

	Иначе

		Сериализатор = СериализаторXDTO;

	КонецЕсли;

КонецПроцедуры

Функция ПредопределенныеТипыПриВыгрузке()

	Типы = Новый Массив;

	Для Каждого ОбъектМетаданных Из Метаданные.Справочники Цикл
		Типы.Добавить(ОбъектМетаданных);
	КонецЦикла;

	Для Каждого ОбъектМетаданных Из Метаданные.ПланыСчетов Цикл
		Типы.Добавить(ОбъектМетаданных);
	КонецЦикла;

	Для Каждого ОбъектМетаданных Из Метаданные.ПланыВидовХарактеристик Цикл
		Типы.Добавить(ОбъектМетаданных);
	КонецЦикла;

	Для Каждого ОбъектМетаданных Из Метаданные.ПланыВидовРасчета Цикл
		Типы.Добавить(ОбъектМетаданных);
	КонецЦикла;

	Возврат Типы;

КонецФункции

// Возвращает фабрику с указанием типов.
//
// Параметры:
//	Типы - ФиксированныйМассив (Метаданные) - массив типов.
//
// Возвращаемое значение:
//	ФабрикаXDTO - фабрика.
//
Функция ПолучитьФабрикуСУказаниемТипов(Знач Типы)

	НаборСхем = ФабрикаXDTO.ЭкспортСхемыXML("http://v8.1c.ru/8.1/data/enterprise/current-config");
	Схема = НаборСхем[0];
	Схема.ОбновитьЭлементDOM();

	УказанныеТипы = Новый Соответствие;
	Для Каждого Тип Из Типы Цикл
		УказанныеТипы.Вставить(XMLТипСсылки(Тип), Истина);
	КонецЦикла;

	ПространствоИмен = Новый Соответствие;
	ПространствоИмен.Вставить("xs", "http://www.w3.org/2001/XMLSchema");
	РазыменовательПространствИменDOM = Новый РазыменовательПространствИменDOM(ПространствоИмен);
	ТекстXPath = "/xs:schema/xs:complexType/xs:sequence/xs:element[starts-with(@type,'tns:')]";

	Запрос = Схема.ДокументDOM.СоздатьВыражениеXPath(ТекстXPath, РазыменовательПространствИменDOM);
	Результат = Запрос.Вычислить(Схема.ДокументDOM);

	Пока Истина Цикл

		УзелПоля = Результат.ПолучитьСледующий();
		Если УзелПоля = Неопределено Тогда
			Прервать;
		КонецЕсли;
		АтрибутТип = УзелПоля.Атрибуты.ПолучитьИменованныйЭлемент("type");
		ТипБезNSПрефикса = Сред(АтрибутТип.ТекстовоеСодержимое, СтрДлина("tns:") + 1);

		Если УказанныеТипы.Получить(ТипБезNSПрефикса) = Неопределено Тогда
			Продолжить;
		КонецЕсли;

		УзелПоля.УстановитьАтрибут("nillable", "true");
		УзелПоля.УдалитьАтрибут("type");
	КонецЦикла;

	ЗаписьXML = Новый ЗаписьXML;
	ИмяФайлаСхемы = ПолучитьИмяВременногоФайла("xsd");
	ЗаписьXML.ОткрытьФайл(ИмяФайлаСхемы);
	ЗаписьDOM = Новый ЗаписьDOM;
	ЗаписьDOM.Записать(Схема.ДокументDOM, ЗаписьXML);
	ЗаписьXML.Закрыть();

	Фабрика = СоздатьФабрикуXDTO(ИмяФайлаСхемы);

	Попытка
		УдалитьФайлы(ИмяФайлаСхемы);
	Исключение
	КонецПопытки;

	Возврат Фабрика;

КонецФункции

// Возвращает имя типа, который будет использован в xml файле для указанного объекта метаданных
// Используется при поиске и замене ссылок при загрузке, при модификации схемы current-config при записи
// 
// Параметры:
//  Значение - Объект метаданных или Ссылка
//
// Возвращаемое значение:
//  Строка - Строка вида AccountingRegisterRecordSet.Хозрасчетный, описывающая объект метаданных 
//
Функция XMLТипСсылки(Знач Значение)

	Если ТипЗнч(Значение) = Тип("ОбъектМетаданных") Тогда
		ОбъектМетаданных = Значение;
		МенеджерОбъекта = МенеджерОбъектаПоПолномуИмени(ОбъектМетаданных.ПолноеИмя());
		Ссылка = МенеджерОбъекта.ПолучитьСсылку();
	Иначе
		ОбъектМетаданных = Значение.Метаданные();
		Ссылка = Значение;
	КонецЕсли;

	Если ОбъектОбразуетСсылочныйТип(ОбъектМетаданных) Тогда

		Возврат СериализаторXDTO.XMLТипЗнч(Ссылка).ИмяТипа;

	Иначе

		ТекстИсключения = НСтр(
			"ru = 'Ошибка при определении XMLТипа ссылки для объекта %1: объект не является ссылочным!'");
		ТекстИсключения = СтрЗаменить(ТекстИсключения, "%1", ОбъектМетаданных.ПолноеИмя());

		ВызватьИсключение ТекстИсключения;

	КонецЕсли;

КонецФункции

// Возвращает менеджер объекта по полному имени объекта метаданных.
// Ограничение: не обрабатываются точки маршрутов бизнес-процессов.
//
// Параметры:
//  ПолноеИмя - Строка - полное имя объекта метаданных. Пример: "Справочник.Организации".
//
// Возвращаемое значение:
//  СправочникМенеджер, ДокументМенеджер.
// 
Функция МенеджерОбъектаПоПолномуИмени(ПолноеИмя)

	ЧастиИмени = РазложитьСтрокуВМассивПодстрок(ПолноеИмя);

	Если ЧастиИмени.Количество() >= 2 Тогда
		КлассОМ = ЧастиИмени[0];
		ИмяОМ = ЧастиИмени[1];
	КонецЕсли;

	Если ВРег(КлассОМ) = "СПРАВОЧНИК" Тогда
		Менеджер = Справочники;
	ИначеЕсли ВРег(КлассОМ) = "ПЛАНВИДОВХАРАКТЕРИСТИК" Тогда
		Менеджер = ПланыВидовХарактеристик;
	ИначеЕсли ВРег(КлассОМ) = "ПЛАНСЧЕТОВ" Тогда
		Менеджер = ПланыСчетов;
	ИначеЕсли ВРег(КлассОМ) = "ПЛАНВИДОВРАСЧЕТА" Тогда
		Менеджер = ПланыВидовРасчета;
	КонецЕсли;

	Возврат Менеджер[ИмяОМ];

КонецФункции

Функция РазложитьСтрокуВМассивПодстрок(Знач Стр, Разделитель = ".")

	МассивСтрок = Новый Массив;
	ДлинаРазделителя = СтрДлина(Разделитель);
	Пока Истина Цикл
		Поз = Найти(Стр, Разделитель);
		Если Поз = 0 Тогда
			Если (СокрЛП(Стр) <> "") Тогда
				МассивСтрок.Добавить(Стр);
			КонецЕсли;
			Возврат МассивСтрок;
		КонецЕсли;
		МассивСтрок.Добавить(Лев(Стр, Поз - 1));
		Стр = Сред(Стр, Поз + ДлинаРазделителя);
	КонецЦикла;

КонецФункции

// Подставляет параметры в строку. Максимально возможное число параметров - 9.
// Параметры в строке задаются как %<номер параметра>. Нумерация параметров начинается с единицы.
//
// Параметры:
//  СтрокаПодстановки  - Строка - шаблон строки с параметрами (вхождениями вида "%ИмяПараметра");
//  Параметр<n>        - Строка - подставляемый параметр.
//
// Возвращаемое значение:
//  Строка   - текстовая строка с подставленными параметрами.
//
// Пример:
//  ПодставитьПараметрыВСтроку(НСтр("ru='%1 пошел в %2'"), "Вася", "Зоопарк") = "Вася пошел в Зоопарк".
//
Функция ПодставитьПараметрыВСтроку(Знач СтрокаПодстановки, Знач Параметр1, Знач Параметр2 = Неопределено,
	Знач Параметр3 = Неопределено, Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено,
	Знач Параметр6 = Неопределено, Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено,
	Знач Параметр9 = Неопределено) Экспорт

	СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%1", Параметр1);
	СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%2", Параметр2);
	СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%3", Параметр3);
	СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%4", Параметр4);
	СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%5", Параметр5);
	СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%6", Параметр6);
	СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%7", Параметр7);
	СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%8", Параметр8);
	СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%9", Параметр9);

	Возврат СтрокаПодстановки;

КонецФункции

ПриЗагрузкеИспользоватьРежимОбменаДанными = Истина;
ПродолжитьЗагрузкуВСлучаеВозникновенияОшибки = Ложь;
ИспользоватьОтборПоДатеДляВсехОбъектов = Истина;
мНаличиеВыгрузкиПодчиненныхОбъектов = Ложь;
//мКоличествоСохраненныхПоследнихВыгрузок = 50;

мТипРезультатЗапроса = Тип("РезультатЗапроса");
мТипДанныхУдаления = Тип("УдалениеОбъекта");

мСоответствиеКолонокДвижений = Новый Соответствие;
ОбработанныхКонстант = 0;
ОбработанныхНаборовЗаписей = 0;
